More stuff...
No binary (build failed)
—
(log yok)
| @@ -7,7 +7,7 @@ | |
| * This allows creation, extraction, and listing of tar files. | |
| * | |
| * Permission to distribute this code under the GPL has been granted. | |
| - | * Modified for busybox by Erik Andersen <[email protected]> <[email protected]> |
| + | * Modified for busybox by Erik Andersen <[email protected]> |
| */ | |
| @@ -15,11 +15,11 @@ | |
| #ifdef BB_TAR | |
| - | const char tar_usage[] = |
| - | "Create, extract, or list files from a TAR file\n\n" |
| - | "usage: tar -[cxtvOf] [tarFileName] [FILE] ...\n" |
| - | "\tc=create, x=extract, t=list contents, v=verbose,\n" |
| - | "\tO=extract to stdout, f=tarfile or \"-\" for stdin\n"; |
| + | const char tar_usage[] = |
| + | "Create, extract, or list files from a TAR file\n\n" |
| + | "usage: tar -[cxtvOf] [tarFileName] [FILE] ...\n" |
| + | "\tc=create, x=extract, t=list contents, v=verbose,\n" |
| + | "\tO=extract to stdout, f=tarfile or \"-\" for stdin\n"; |
| @@ -42,24 +42,23 @@ const char tar_usage[] = | |
| * This structure is always embedded in a TAR_BLOCK_SIZE sized block | |
| * with zero padding. We only process this information minimally. | |
| */ | |
| - | typedef struct |
| - | { |
| - | char name[TAR_NAME_SIZE]; |
| - | char mode[8]; |
| - | char uid[8]; |
| - | char gid[8]; |
| - | char size[12]; |
| - | char mtime[12]; |
| - | char checkSum[8]; |
| - | char typeFlag; |
| - | char linkName[TAR_NAME_SIZE]; |
| - | char magic[6]; |
| - | char version[2]; |
| - | char uname[32]; |
| - | char gname[32]; |
| - | char devMajor[8]; |
| - | char devMinor[8]; |
| - | char prefix[155]; |
| + | typedef struct { |
| + | char name[TAR_NAME_SIZE]; |
| + | char mode[8]; |
| + | char uid[8]; |
| + | char gid[8]; |
| + | char size[12]; |
| + | char mtime[12]; |
| + | char checkSum[8]; |
| + | char typeFlag; |
| + | char linkName[TAR_NAME_SIZE]; |
| + | char magic[6]; |
| + | char version[2]; |
| + | char uname[32]; |
| + | char gname[32]; |
| + | char devMajor[8]; |
| + | char devMinor[8]; |
| + | char prefix[155]; |
| } TarHeader; | |
| #define TAR_MAGIC "ustar" | |
| @@ -73,168 +72,162 @@ typedef struct | |
| /* | |
| * Static data. | |
| */ | |
| - | 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]; |
| + | 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]; |
| /* | |
| * Static data associated with the tar file. | |
| */ | |
| - | static const char * tarName; |
| - | static int tarFd; |
| - | static dev_t tarDev; |
| - | static ino_t tarInode; |
| + | static const char *tarName; |
| + | static int tarFd; |
| + | static dev_t tarDev; |
| + | static ino_t tarInode; |
| /* | |
| * Local procedures to restore files from a tar file. | |
| */ | |
| - | 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 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, |
| - | int fileCount, char ** fileTable); |
| + | static void readHeader (const TarHeader * hp, |
| + | int fileCount, char **fileTable); |
| /* | |
| * Local procedures to save files into a tar file. | |
| */ | |
| - | static void saveFile(const char * fileName, int seeLinks); |
| + | static void saveFile (const char *fileName, int seeLinks); |
| - | static void saveRegularFile(const char * fileName, |
| - | const struct stat * statbuf); |
| + | static void saveRegularFile (const char *fileName, |
| + | const struct stat *statbuf); |
| - | static void saveDirectory(const char * fileName, |
| - | const struct stat * statbuf); |
| + | static void saveDirectory (const char *fileName, |
| + | const struct stat *statbuf); |
| - | static int wantFileName(const char * fileName, |
| - | int fileCount, char ** fileTable); |
| + | static int wantFileName (const char *fileName, |
| + | int fileCount, char **fileTable); |
| - | static void writeHeader(const char * fileName, |
| - | const struct stat * statbuf); |
| + | static void writeHeader (const char *fileName, const struct stat *statbuf); |
| - | static void writeTarFile(int fileCount, char ** fileTable); |
| - | static void writeTarBlock(const char * buf, int len); |
| - | static int putOctal(char * cp, int len, long value); |
| + | static void writeTarFile (int fileCount, char **fileTable); |
| + | static void writeTarBlock (const char *buf, int len); |
| + | static int putOctal (char *cp, int len, long value); |
| - | extern int |
| - | tar_main(int argc, char ** argv) |
| + | extern int tar_main (int argc, char **argv) |
| { | |
| - | const char * options; |
| - | |
| - | argc--; |
| - | argv++; |
| - | |
| - | if (argc < 1) |
| - | { |
| - | fprintf(stderr, "%s", tar_usage); |
| - | return 1; |
| - | } |
| - | |
| - | |
| - | errorFlag = FALSE; |
| - | extractFlag = FALSE; |
| - | createFlag = FALSE; |
| - | listFlag = FALSE; |
| - | verboseFlag = FALSE; |
| - | tostdoutFlag = FALSE; |
| - | tarName = NULL; |
| - | tarDev = 0; |
| - | tarInode = 0; |
| - | tarFd = -1; |
| - | |
| - | /* |
| - | * Parse the options. |
| - | */ |
| - | options = *argv++; |
| - | argc--; |
| - | |
| - | if (**argv == '-') { |
| - | for (; *options; options++) |
| - | { |
| - | switch (*options) |
| - | { |
| - | case 'f': |
| - | if (tarName != NULL) |
| - | { |
| - | fprintf(stderr, "Only one 'f' option allowed\n"); |
| - | |
| - | return 1; |
| - | } |
| - | |
| - | tarName = *argv++; |
| - | argc--; |
| - | |
| - | break; |
| + | const char *options; |
| + | |
| + | argc--; |
| + | argv++; |
| + | |
| + | if (argc < 1) { |
| + | fprintf (stderr, "%s", tar_usage); |
| + | exit (FALSE); |
| + | } |
| + | |
| + | |
| + | errorFlag = FALSE; |
| + | extractFlag = FALSE; |
| + | createFlag = FALSE; |
| + | listFlag = FALSE; |
| + | verboseFlag = FALSE; |
| + | tostdoutFlag = FALSE; |
| + | tarName = NULL; |
| + | tarDev = 0; |
| + | tarInode = 0; |
| + | tarFd = -1; |
| + | |
| + | /* |
| + | * Parse the options. |
| + | */ |
| + | options = *argv++; |
| + | argc--; |
| + | |
| + | if (**argv == '-') { |
| + | for (; *options; options++) { |
| + | switch (*options) { |
| + | case 'f': |
| + | if (tarName != NULL) { |
| + | fprintf (stderr, "Only one 'f' option allowed\n"); |
| + | |
| + | exit (FALSE); |
| + | } |
| - | case 't': |
| - | listFlag = TRUE; |
| - | break; |
| + | tarName = *argv++; |
| + | argc--; |
| - | case 'x': |
| - | extractFlag = TRUE; |
| - | break; |
| + | break; |
| - | case 'c': |
| - | createFlag = TRUE; |
| - | break; |
| + | case 't': |
| + | listFlag = TRUE; |
| + | break; |
| - | case 'v': |
| - | verboseFlag = TRUE; |
| - | break; |
| + | case 'x': |
| + | extractFlag = TRUE; |
| + | break; |
| - | case 'O': |
| - | tostdoutFlag = TRUE; |
| - | break; |
| + | case 'c': |
| + | createFlag = TRUE; |
| + | break; |
| - | case '-': |
| - | break; |
| + | case 'v': |
| + | verboseFlag = TRUE; |
| + | break; |
| - | default: |
| - | fprintf(stderr, "Unknown tar flag '%c'\n", *options); |
| + | case 'O': |
| + | tostdoutFlag = TRUE; |
| + | break; |
| - | return 1; |
| - | } |
| - | } |
| - | } |
| + | case '-': |
| + | break; |
| - | /* |
| - | * Validate the options. |
| - | */ |
| - | if (extractFlag + listFlag + createFlag != 1) |
| - | { |
| - | fprintf(stderr, "Exactly one of 'c', 'x' or 't' must be specified\n"); |
| + | default: |
| + | fprintf (stderr, "Unknown tar flag '%c'\n", *options); |
| - | return 1; |
| + | exit (FALSE); |
| + | } |
| } | |
| - | |
| - | /* |
| - | * Do the correct type of action supplying the rest of the |
| - | * command line arguments as the list of files to process. |
| - | */ |
| - | if (createFlag) |
| - | writeTarFile(argc, argv); |
| - | else |
| - | readTarFile(argc, argv); |
| - | if (errorFlag) |
| - | fprintf(stderr, "\n"); |
| - | return( errorFlag); |
| + | } |
| + | |
| + | /* |
| + | * Validate the options. |
| + | */ |
| + | if (extractFlag + listFlag + createFlag != 1) { |
| + | fprintf (stderr, |
| + | "Exactly one of 'c', 'x' or 't' must be specified\n"); |
| + | |
| + | exit (FALSE); |
| + | } |
| + | |
| + | /* |
| + | * Do the correct type of action supplying the rest of the |
| + | * command line arguments as the list of files to process. |
| + | */ |
| + | if (createFlag) |
| + | writeTarFile (argc, argv); |
| + | else |
| + | readTarFile (argc, argv); |
| + | if (errorFlag) |
| + | fprintf (stderr, "\n"); |
| + | exit (errorFlag); |
| } | |
| @@ -242,128 +235,119 @@ tar_main(int argc, char ** argv) | |
| * Read a tar file and extract or list the specified files within it. | |
| * If the list is empty than all files are extracted or listed. | |
| */ | |
| - | static void |
| - | readTarFile(int fileCount, char ** fileTable) |
| + | static void readTarFile (int fileCount, char **fileTable) |
| { | |
| - | const char * cp; |
| - | int cc; |
| - | int inCc; |
| - | int blockSize; |
| - | char buf[BUF_SIZE]; |
| - | |
| - | skipFileFlag = FALSE; |
| - | badHeader = FALSE; |
| - | warnedRoot = FALSE; |
| - | eofFlag = FALSE; |
| - | inHeader = TRUE; |
| - | inCc = 0; |
| - | dataCc = 0; |
| - | outFd = -1; |
| - | blockSize = sizeof(buf); |
| - | cp = buf; |
| - | |
| - | /* |
| - | * Open the tar file for reading. |
| + | const char *cp; |
| + | int cc; |
| + | int inCc; |
| + | int blockSize; |
| + | char buf[BUF_SIZE]; |
| + | |
| + | skipFileFlag = FALSE; |
| + | badHeader = FALSE; |
| + | warnedRoot = FALSE; |
| + | eofFlag = FALSE; |
| + | inHeader = TRUE; |
| + | inCc = 0; |
| + | dataCc = 0; |
| + | outFd = -1; |
| + | blockSize = sizeof (buf); |
| + | cp = buf; |
| + | |
| + | /* |
| + | * Open the tar file for reading. |
| + | */ |
| + | if ((tarName == NULL) || !strcmp (tarName, "-")) { |
| + | tarFd = STDIN; |
| + | } else |
| + | tarFd = open (tarName, O_RDONLY); |
| + | |
| + | if (tarFd < 0) { |
| + | perror (tarName); |
| + | errorFlag = TRUE; |
| + | return; |
| + | } |
| + | |
| + | /* |
| + | * Read blocks from the file until an end of file header block |
| + | * has been seen. (A real end of file from a read is an error.) |
| + | */ |
| + | while (!eofFlag) { |
| + | /* |
| + | * Read the next block of data if necessary. |
| + | * This will be a large block if possible, which we will |
| + | * then process in the small tar blocks. |
| */ | |
| - | if ( (tarName==NULL) || !strcmp( tarName, "-") ) { |
| - | tarFd = STDIN; |
| - | } |
| - | else |
| - | tarFd = open(tarName, O_RDONLY); |
| + | if (inCc <= 0) { |
| + | cp = buf; |
| + | inCc = fullRead (tarFd, buf, blockSize); |
| - | if (tarFd < 0) |
| - | { |
| - | perror(tarName); |
| + | if (inCc < 0) { |
| + | perror (tarName); |
| errorFlag = TRUE; | |
| - | return; |
| + | goto done; |
| + | } |
| + | |
| + | if (inCc == 0) { |
| + | fprintf (stderr, |
| + | "Unexpected end of file from \"%s\"", tarName); |
| + | errorFlag = TRUE; |
| + | goto done; |
| + | } |
| } | |
| - | /* |
| - | * Read blocks from the file until an end of file header block |
| - | * has been seen. (A real end of file from a read is an error.) |
| + | /* |
| + | * If we are expecting a header block then examine it. |
| */ | |
| - | while (!eofFlag) |
| - | { |
| - | /* |
| - | * Read the next block of data if necessary. |
| - | * This will be a large block if possible, which we will |
| - | * then process in the small tar blocks. |
| - | */ |
| - | if (inCc <= 0) |
| - | { |
| - | cp = buf; |
| - | inCc = fullRead(tarFd, buf, blockSize); |
| - | |
| - | if (inCc < 0) |
| - | { |
| - | perror(tarName); |
| - | errorFlag=TRUE; |
| - | goto done; |
| - | } |
| - | |
| - | if (inCc == 0) |
| - | { |
| - | fprintf(stderr, |
| - | "Unexpected end of file from \"%s\"", |
| - | tarName); |
| - | errorFlag=TRUE; |
| - | goto done; |
| - | } |
| - | } |
| + | if (inHeader) { |
| + | readHeader ((const TarHeader *) cp, fileCount, fileTable); |
| - | /* |
| - | * If we are expecting a header block then examine it. |
| - | */ |
| - | if (inHeader) |
| - | { |
| - | readHeader((const TarHeader *) cp, fileCount, fileTable); |
| + | cp += TAR_BLOCK_SIZE; |
| + | inCc -= TAR_BLOCK_SIZE; |
| - | cp += TAR_BLOCK_SIZE; |
| - | inCc -= TAR_BLOCK_SIZE; |
| - | |
| - | continue; |
| - | } |
| - | |
| - | /* |
| - | * We are currently handling the data for a file. |
| - | * Process the minimum of the amount of data we have available |
| - | * and the amount left to be processed for the file. |
| - | */ |
| - | cc = inCc; |
| - | |
| - | if (cc > dataCc) |
| - | cc = dataCc; |
| - | |
| - | readData(cp, cc); |
| - | |
| - | /* |
| - | * If the amount left isn't an exact multiple of the tar block |
| - | * size then round it up to the next block boundary since there |
| - | * is padding at the end of the file. |
| - | */ |
| - | if (cc % TAR_BLOCK_SIZE) |
| - | cc += TAR_BLOCK_SIZE - (cc % TAR_BLOCK_SIZE); |
| - | |
| - | cp += cc; |
| - | inCc -= cc; |
| + | continue; |
| } | |
| - | done: |
| - | /* |
| - | * Close the tar file if needed. |
| + | /* |
| + | * We are currently handling the data for a file. |
| + | * Process the minimum of the amount of data we have available |
| + | * and the amount left to be processed for the file. |
| */ | |
| - | if ((tarFd >= 0) && (close(tarFd) < 0)) |
| - | perror(tarName); |
| + | cc = inCc; |
| + | |
| + | if (cc > dataCc) |
| + | cc = dataCc; |
| - | /* |
| - | * Close the output file if needed. |
| - | * This is only done here on a previous error and so no |
| - | * message is required on errors. |
| + | readData (cp, cc); |
| + | |
| + | /* |
| + | * If the amount left isn't an exact multiple of the tar block |
| + | * size then round it up to the next block boundary since there |
| + | * is padding at the end of the file. |
| */ | |
| - | if (tostdoutFlag==FALSE) { |
| - | if (outFd >= 0) |
| - | (void) close(outFd); |
| - | } |
| + | if (cc % TAR_BLOCK_SIZE) |
| + | cc += TAR_BLOCK_SIZE - (cc % TAR_BLOCK_SIZE); |
| + | |
| + | cp += cc; |
| + | inCc -= cc; |
| + | } |
| + | |
| + | done: |
| + | /* |
| + | * Close the tar file if needed. |
| + | */ |
| + | if ((tarFd >= 0) && (close (tarFd) < 0)) |
| + | perror (tarName); |
| + | |
| + | /* |
| + | * Close the output file if needed. |
| + | * This is only done here on a previous error and so no |
| + | * message is required on errors. |
| + | */ |
| + | if (tostdoutFlag == FALSE) { |
| + | if (outFd >= 0) |
| + | (void) close (outFd); |
| + | } |
| } | |
| @@ -373,332 +357,307 @@ done: | |
| * the end of the tar file. | |
| */ | |
| static void | |
| - | readHeader(const TarHeader * hp, int fileCount, char ** fileTable) |
| + | readHeader (const TarHeader * hp, int fileCount, char **fileTable) |
| { | |
| - | int mode; |
| - | int uid; |
| - | int gid; |
| - | int checkSum; |
| - | long size; |
| - | time_t mtime; |
| - | const char * name; |
| - | int cc; |
| - | int hardLink; |
| - | int softLink; |
| - | |
| - | /* |
| - | * If the block is completely empty, then this is the end of the |
| - | * archive file. If the name is null, then just skip this header. |
| - | */ |
| - | name = hp->name; |
| - | |
| - | if (*name == '\0') |
| - | { |
| - | for (cc = TAR_BLOCK_SIZE; cc > 0; cc--) |
| - | { |
| - | if (*name++) |
| - | return; |
| - | } |
| - | |
| - | eofFlag = TRUE; |
| - | |
| + | int mode; |
| + | int uid; |
| + | int gid; |
| + | int checkSum; |
| + | long size; |
| + | time_t mtime; |
| + | const char *name; |
| + | int cc; |
| + | int hardLink; |
| + | int softLink; |
| + | |
| + | /* |
| + | * If the block is completely empty, then this is the end of the |
| + | * archive file. If the name is null, then just skip this header. |
| + | */ |
| + | name = hp->name; |
| + | |
| + | if (*name == '\0') { |
| + | for (cc = TAR_BLOCK_SIZE; cc > 0; cc--) { |
| + | if (*name++) |
| return; | |
| } | |
| - | /* |
| - | * There is another file in the archive to examine. |
| - | * Extract the encoded information and check it. |
| - | */ |
| - | mode = getOctal(hp->mode, sizeof(hp->mode)); |
| - | uid = getOctal(hp->uid, sizeof(hp->uid)); |
| - | gid = getOctal(hp->gid, sizeof(hp->gid)); |
| - | size = getOctal(hp->size, sizeof(hp->size)); |
| - | mtime = getOctal(hp->mtime, sizeof(hp->mtime)); |
| - | checkSum = getOctal(hp->checkSum, sizeof(hp->checkSum)); |
| + | eofFlag = TRUE; |
| - | if ((mode < 0) || (uid < 0) || (gid < 0) || (size < 0)) |
| - | { |
| - | if (!badHeader) |
| - | fprintf(stderr, "Bad tar header, skipping\n"); |
| + | return; |
| + | } |
| - | badHeader = TRUE; |
| + | /* |
| + | * There is another file in the archive to examine. |
| + | * Extract the encoded information and check it. |
| + | */ |
| + | mode = getOctal (hp->mode, sizeof (hp->mode)); |
| + | uid = getOctal (hp->uid, sizeof (hp->uid)); |
| + | gid = getOctal (hp->gid, sizeof (hp->gid)); |
| + | size = getOctal (hp->size, sizeof (hp->size)); |
| + | mtime = getOctal (hp->mtime, sizeof (hp->mtime)); |
| + | checkSum = getOctal (hp->checkSum, sizeof (hp->checkSum)); |
| - | return; |
| - | } |
| + | if ((mode < 0) || (uid < 0) || (gid < 0) || (size < 0)) { |
| + | if (!badHeader) |
| + | fprintf (stderr, "Bad tar header, skipping\n"); |
| - | badHeader = FALSE; |
| - | skipFileFlag = FALSE; |
| + | badHeader = TRUE; |
| - | /* |
| - | * Check for the file modes. |
| - | */ |
| - | hardLink = ((hp->typeFlag == TAR_TYPE_HARD_LINK) || |
| + | return; |
| + | } |
| + | |
| + | badHeader = FALSE; |
| + | skipFileFlag = FALSE; |
| + | |
| + | /* |
| + | * Check for the file modes. |
| + | */ |
| + | hardLink = ((hp->typeFlag == TAR_TYPE_HARD_LINK) || |
| (hp->typeFlag == TAR_TYPE_HARD_LINK - '0')); | |
| - | softLink = ((hp->typeFlag == TAR_TYPE_SOFT_LINK) || |
| + | softLink = ((hp->typeFlag == TAR_TYPE_SOFT_LINK) || |
| (hp->typeFlag == TAR_TYPE_SOFT_LINK - '0')); | |
| - | /* |
| - | * Check for a directory or a regular file. |
| - | */ |
| - | if (name[strlen(name) - 1] == '/') |
| - | mode |= S_IFDIR; |
| - | else if ((mode & S_IFMT) == 0) |
| - | mode |= S_IFREG; |
| - | |
| - | /* |
| - | * Check for absolute paths in the file. |
| - | * If we find any, then warn the user and make them relative. |
| - | */ |
| - | if (*name == '/') |
| - | { |
| - | while (*name == '/') |
| - | name++; |
| - | |
| - | if (!warnedRoot) |
| - | { |
| - | fprintf(stderr, |
| - | "Absolute path detected, removing leading slashes\n"); |
| - | } |
| - | |
| - | warnedRoot = TRUE; |
| + | /* |
| + | * Check for a directory or a regular file. |
| + | */ |
| + | if (name[strlen (name) - 1] == '/') |
| + | mode |= S_IFDIR; |
| + | else if ((mode & S_IFMT) == 0) |
| + | mode |= S_IFREG; |
| + | |
| + | /* |
| + | * Check for absolute paths in the file. |
| + | * If we find any, then warn the user and make them relative. |
| + | */ |
| + | if (*name == '/') { |
| + | while (*name == '/') |
| + | name++; |
| + | |
| + | if (!warnedRoot) { |
| + | fprintf (stderr, |
| + | "Absolute path detected, removing leading slashes\n"); |
| } | |
| - | /* |
| - | * See if we want this file to be restored. |
| - | * If not, then set up to skip it. |
| - | */ |
| - | if (!wantFileName(name, fileCount, fileTable)) |
| - | { |
| - | if (!hardLink && !softLink && S_ISREG(mode)) |
| - | { |
| - | inHeader = (size == 0); |
| - | dataCc = size; |
| - | } |
| - | |
| - | skipFileFlag = TRUE; |
| - | |
| - | return; |
| + | warnedRoot = TRUE; |
| + | } |
| + | |
| + | /* |
| + | * See if we want this file to be restored. |
| + | * If not, then set up to skip it. |
| + | */ |
| + | if (!wantFileName (name, fileCount, fileTable)) { |
| + | if (!hardLink && !softLink && S_ISREG (mode)) { |
| + | inHeader = (size == 0); |
| + | dataCc = size; |
| } | |
| - | /* |
| - | * This file is to be handled. |
| - | * If we aren't extracting then just list information about the file. |
| - | */ |
| - | if (!extractFlag) |
| - | { |
| - | if (verboseFlag) |
| - | { |
| - | printf("%s %3d/%-d %9ld %s %s", modeString(mode), |
| - | uid, gid, size, timeString(mtime), name); |
| - | } |
| - | else |
| - | printf("%s", name); |
| - | |
| - | if (hardLink) |
| - | printf(" (link to \"%s\")", hp->linkName); |
| - | else if (softLink) |
| - | printf(" (symlink to \"%s\")", hp->linkName); |
| - | else if (S_ISREG(mode)) |
| - | { |
| - | inHeader = (size == 0); |
| - | dataCc = size; |
| - | } |
| - | |
| - | printf("\n"); |
| + | skipFileFlag = TRUE; |
| - | return; |
| - | } |
| + | return; |
| + | } |
| - | /* |
| - | * We really want to extract the file. |
| - | */ |
| - | if (verboseFlag) |
| - | printf("x %s\n", name); |
| + | /* |
| + | * This file is to be handled. |
| + | * If we aren't extracting then just list information about the file. |
| + | */ |
| + | if (!extractFlag) { |
| + | if (verboseFlag) { |
| + | printf ("%s %3d/%-d %9ld %s %s", modeString (mode), |
| + | uid, gid, size, timeString (mtime), name); |
| + | } else |
| + | printf ("%s", name); |
| if (hardLink) | |
| - | { |
| - | if (link(hp->linkName, name) < 0) |
| - | perror(name); |
| - | |
| - | return; |
| - | } |
| - | |
| - | if (softLink) |
| - | { |
| - | #ifdef S_ISLNK |
| - | if (symlink(hp->linkName, name) < 0) |
| - | perror(name); |
| - | #else |
| - | fprintf(stderr, "Cannot create symbolic links\n"); |
| - | #endif |
| - | return; |
| + | printf (" (link to \"%s\")", hp->linkName); |
| + | else if (softLink) |
| + | printf (" (symlink to \"%s\")", hp->linkName); |
| + | else if (S_ISREG (mode)) { |
| + | inHeader = (size == 0); |
| + | dataCc = size; |
| } | |
| - | /* |
| - | * If the file is a directory, then just create the path. |
| - | */ |
| - | if (S_ISDIR(mode)) |
| - | { |
| - | createPath(name, mode); |
| + | printf ("\n"); |
| - | return; |
| - | } |
| + | return; |
| + | } |
| - | /* |
| - | * There is a file to write. |
| - | * First create the path to it if necessary with a default permission. |
| - | */ |
| - | createPath(name, 0777); |
| + | /* |
| + | * We really want to extract the file. |
| + | */ |
| + | if (verboseFlag) |
| + | printf ("x %s\n", name); |
| - | inHeader = (size == 0); |
| - | dataCc = size; |
| + | if (hardLink) { |
| + | if (link (hp->linkName, name) < 0) |
| + | perror (name); |
| - | /* |
| - | * Start the output file. |
| - | */ |
| - | if (tostdoutFlag==TRUE) |
| - | outFd = STDOUT; |
| - | else |
| - | outFd = open(name, O_WRONLY | O_CREAT | O_TRUNC, mode); |
| - | |
| - | if (outFd < 0) |
| - | { |
| - | perror(name); |
| - | skipFileFlag = TRUE; |
| - | return; |
| - | } |
| + | return; |
| + | } |
| - | /* |
| - | * If the file is empty, then that's all we need to do. |
| - | */ |
| - | if (size == 0 && tostdoutFlag == FALSE) |
| - | { |
| - | (void) close(outFd); |
| - | outFd = -1; |
| - | } |
| + | if (softLink) { |
| + | #ifdef S_ISLNK |
| + | if (symlink (hp->linkName, name) < 0) |
| + | perror (name); |
| + | #else |
| + | fprintf (stderr, "Cannot create symbolic links\n"); |
| + | #endif |
| + | return; |
| + | } |
| + | |
| + | /* |
| + | * If the file is a directory, then just create the path. |
| + | */ |
| + | if (S_ISDIR (mode)) { |
| + | createPath (name, mode); |
| + | |
| + | return; |
| + | } |
| + | |
| + | /* |
| + | * There is a file to write. |
| + | * First create the path to it if necessary with a default permission. |
| + | */ |
| + | createPath (name, 0777); |
| + | |
| + | inHeader = (size == 0); |
| + | dataCc = size; |
| + | |
| + | /* |
| + | * Start the output file. |
| + | */ |
| + | if (tostdoutFlag == TRUE) |
| + | outFd = STDOUT; |
| + | else |
| + | outFd = open (name, O_WRONLY | O_CREAT | O_TRUNC, mode); |
| + | |
| + | if (outFd < 0) { |
| + | perror (name); |
| + | skipFileFlag = TRUE; |
| + | return; |
| + | } |
| + | |
| + | /* |
| + | * If the file is empty, then that's all we need to do. |
| + | */ |
| + | if (size == 0 && tostdoutFlag == FALSE) { |
| + | (void) close (outFd); |
| + | outFd = -1; |
| + | } |
| } | |
| /* | |
| * Handle a data block of some specified size that was read. | |
| */ | |
| - | static void |
| - | readData(const char * cp, int count) |
| + | static void readData (const char *cp, int count) |
| { | |
| - | /* |
| - | * Reduce the amount of data left in this file. |
| - | * If there is no more data left, then we need to read |
| - | * the header again. |
| - | */ |
| - | dataCc -= count; |
| - | |
| - | if (dataCc <= 0) |
| - | inHeader = TRUE; |
| - | |
| - | /* |
| - | * If we aren't extracting files or this file is being |
| - | * skipped then do nothing more. |
| - | */ |
| - | if (!extractFlag || skipFileFlag) |
| - | return; |
| + | /* |
| + | * Reduce the amount of data left in this file. |
| + | * If there is no more data left, then we need to read |
| + | * the header again. |
| + | */ |
| + | dataCc -= count; |
| + | |
| + | if (dataCc <= 0) |
| + | inHeader = TRUE; |
| - | /* |
| - | * Write the data to the output file. |
| - | */ |
| - | if (fullWrite(outFd, cp, count) < 0) |
| - | { |
| - | perror(outName); |
| - | if (tostdoutFlag==FALSE) { |
| - | (void) close(outFd); |
| - | outFd = -1; |
| - | } |
| - | skipFileFlag = TRUE; |
| - | return; |
| + | /* |
| + | * If we aren't extracting files or this file is being |
| + | * skipped then do nothing more. |
| + | */ |
| + | if (!extractFlag || skipFileFlag) |
| + | return; |
| + | |
| + | /* |
| + | * Write the data to the output file. |
| + | */ |
| + | if (fullWrite (outFd, cp, count) < 0) { |
| + | perror (outName); |
| + | if (tostdoutFlag == FALSE) { |
| + | (void) close (outFd); |
| + | outFd = -1; |
| } | |
| + | skipFileFlag = TRUE; |
| + | return; |
| + | } |
| + | |
| + | /* |
| + | * If the write failed, close the file and disable further |
| + | * writes to this file. |
| + | */ |
| + | if (dataCc <= 0 && tostdoutFlag == FALSE) { |
| + | if (close (outFd)) |
| + | perror (outName); |
| - | /* |
| - | * If the write failed, close the file and disable further |
| - | * writes to this file. |
| - | */ |
| - | if (dataCc <= 0 && tostdoutFlag==FALSE) |
| - | { |
| - | if (close(outFd)) |
| - | perror(outName); |
| - | |
| - | outFd = -1; |
| - | } |
| + | outFd = -1; |
| + | } |
| } | |
| /* | |
| * Write a tar file containing the specified files. | |
| */ | |
| - | static void |
| - | writeTarFile(int fileCount, char ** fileTable) |
| + | static void writeTarFile (int fileCount, char **fileTable) |
| { | |
| - | struct stat statbuf; |
| - | |
| - | /* |
| - | * Make sure there is at least one file specified. |
| - | */ |
| - | if (fileCount <= 0) |
| - | { |
| - | fprintf(stderr, "No files specified to be saved\n"); |
| - | errorFlag=TRUE; |
| - | } |
| - | |
| - | /* |
| - | * Create the tar file for writing. |
| - | */ |
| - | if ( (tarName==NULL) || !strcmp( tarName, "-") ) { |
| - | tostdoutFlag = TRUE; |
| - | tarFd = STDOUT; |
| - | } |
| - | else |
| - | tarFd = open(tarName, O_WRONLY | O_CREAT | O_TRUNC, 0666); |
| - | |
| - | if (tarFd < 0) |
| - | { |
| - | perror(tarName); |
| - | errorFlag=TRUE; |
| - | return; |
| - | } |
| - | |
| - | /* |
| - | * Get the device and inode of the tar file for checking later. |
| - | */ |
| - | if (fstat(tarFd, &statbuf) < 0) |
| - | { |
| - | perror(tarName); |
| - | errorFlag = TRUE; |
| - | goto done; |
| - | } |
| - | |
| - | tarDev = statbuf.st_dev; |
| - | tarInode = statbuf.st_ino; |
| - | |
| - | /* |
| - | * Append each file name into the archive file. |
| - | * Follow symbolic links for these top level file names. |
| - | */ |
| - | while (!errorFlag && (fileCount-- > 0)) |
| - | { |
| - | saveFile(*fileTable++, FALSE); |
| - | } |
| - | |
| - | /* |
| - | * Now write an empty block of zeroes to end the archive. |
| - | */ |
| - | writeTarBlock("", 1); |
| - | |
| - | |
| - | done: |
| - | /* |
| - | * Close the tar file and check for errors if it was opened. |
| - | */ |
| - | if ( (tostdoutFlag==FALSE) && (tarFd >= 0) && (close(tarFd) < 0)) |
| - | perror(tarName); |
| + | struct stat statbuf; |
| + | |
| + | /* |
| + | * Make sure there is at least one file specified. |
| + | */ |
| + | if (fileCount <= 0) { |
| + | fprintf (stderr, "No files specified to be saved\n"); |
| + | errorFlag = TRUE; |
| + | } |
| + | |
| + | /* |
| + | * Create the tar file for writing. |
| + | */ |
| + | if ((tarName == NULL) || !strcmp (tarName, "-")) { |
| + | tostdoutFlag = TRUE; |
| + | tarFd = STDOUT; |
| + | } else |
| + | tarFd = open (tarName, O_WRONLY | O_CREAT | O_TRUNC, 0666); |
| + | |
| + | if (tarFd < 0) { |
| + | perror (tarName); |
| + | errorFlag = TRUE; |
| + | return; |
| + | } |
| + | |
| + | /* |
| + | * Get the device and inode of the tar file for checking later. |
| + | */ |
| + | if (fstat (tarFd, &statbuf) < 0) { |
| + | perror (tarName); |
| + | errorFlag = TRUE; |
| + | goto done; |
| + | } |
| + | |
| + | tarDev = statbuf.st_dev; |
| + | tarInode = statbuf.st_ino; |
| + | |
| + | /* |
| + | * Append each file name into the archive file. |
| + | * Follow symbolic links for these top level file names. |
| + | */ |
| + | while (!errorFlag && (fileCount-- > 0)) { |
| + | saveFile (*fileTable++, FALSE); |
| + | } |
| + | |
| + | /* |
| + | * Now write an empty block of zeroes to end the archive. |
| + | */ |
| + | writeTarBlock ("", 1); |
| + | |
| + | |
| + | done: |
| + | /* |
| + | * Close the tar file and check for errors if it was opened. |
| + | */ |
| + | if ((tostdoutFlag == FALSE) && (tarFd >= 0) && (close (tarFd) < 0)) |
| + | perror (tarName); |
| } | |
| @@ -709,76 +668,70 @@ done: | |
| * flag indicates whether or not we want to see symbolic links as | |
| * they really are, instead of blindly following them. | |
| */ | |
| - | static void |
| - | saveFile(const char * fileName, int seeLinks) |
| + | static void saveFile (const char *fileName, int seeLinks) |
| { | |
| - | int status; |
| - | int mode; |
| - | struct stat statbuf; |
| + | int status; |
| + | int mode; |
| + | struct stat statbuf; |
| - | if (verboseFlag) |
| - | printf("a %s\n", fileName); |
| + | if (verboseFlag) |
| + | printf ("a %s\n", fileName); |
| - | /* |
| - | * Check that the file name will fit in the header. |
| - | */ |
| - | if (strlen(fileName) >= TAR_NAME_SIZE) |
| - | { |
| - | fprintf(stderr, "%s: File name is too long\n", fileName); |
| + | /* |
| + | * Check that the file name will fit in the header. |
| + | */ |
| + | if (strlen (fileName) >= TAR_NAME_SIZE) { |
| + | fprintf (stderr, "%s: File name is too long\n", fileName); |
| - | return; |
| - | } |
| + | return; |
| + | } |
| - | /* |
| - | * Find out about the file. |
| - | */ |
| + | /* |
| + | * Find out about the file. |
| + | */ |
| #ifdef S_ISLNK | |
| - | if (seeLinks) |
| - | status = lstat(fileName, &statbuf); |
| - | else |
| + | if (seeLinks) |
| + | status = lstat (fileName, &statbuf); |
| + | else |
| #endif | |
| - | status = stat(fileName, &statbuf); |
| + | status = stat (fileName, &statbuf); |
| - | if (status < 0) |
| - | { |
| - | perror(fileName); |
| + | if (status < 0) { |
| + | perror (fileName); |
| - | return; |
| - | } |
| + | return; |
| + | } |
| - | /* |
| - | * Make sure we aren't trying to save our file into itself. |
| - | */ |
| - | if ((statbuf.st_dev == tarDev) && (statbuf.st_ino == tarInode)) |
| - | { |
| - | fprintf(stderr, "Skipping saving of archive file itself\n"); |
| + | /* |
| + | * Make sure we aren't trying to save our file into itself. |
| + | */ |
| + | if ((statbuf.st_dev == tarDev) && (statbuf.st_ino == tarInode)) { |
| + | fprintf (stderr, "Skipping saving of archive file itself\n"); |
| - | return; |
| - | } |
| + | return; |
| + | } |
| - | /* |
| - | * Check the type of file. |
| - | */ |
| - | mode = statbuf.st_mode; |
| + | /* |
| + | * Check the type of file. |
| + | */ |
| + | mode = statbuf.st_mode; |
| - | if (S_ISDIR(mode)) |
| - | { |
| - | saveDirectory(fileName, &statbuf); |
| + | if (S_ISDIR (mode)) { |
| + | saveDirectory (fileName, &statbuf); |
| - | return; |
| - | } |
| + | return; |
| + | } |
| - | if (S_ISREG(mode)) |
| - | { |
| - | saveRegularFile(fileName, &statbuf); |
| + | if (S_ISREG (mode)) { |
| + | saveRegularFile (fileName, &statbuf); |
| - | return; |
| - | } |
| + | return; |
| + | } |
| - | /* |
| - | * The file is a strange type of file, ignore it. |
| - | */ |
| - | fprintf(stderr, "%s: not a directory or regular file\n", fileName); |
| + | /* |
| + | * The file is a strange type of file, ignore it. |
| + | */ |
| + | fprintf (stderr, "%s: not a directory or regular file\n", fileName); |
| } | |
| @@ -786,183 +739,173 @@ saveFile(const char * fileName, int seeLinks) | |
| * Save a regular file to the tar file. | |
| */ | |
| static void | |
| - | saveRegularFile(const char * fileName, const struct stat * statbuf) |
| + | saveRegularFile (const char *fileName, const struct stat *statbuf) |
| { | |
| - | int sawEof; |
| - | int fileFd; |
| - | int cc; |
| - | int dataCount; |
| - | long fullDataCount; |
| - | char data[TAR_BLOCK_SIZE * 16]; |
| - | |
| - | /* |
| - | * Open the file for reading. |
| + | int sawEof; |
| + | int fileFd; |
| + | int cc; |
| + | int dataCount; |
| + | long fullDataCount; |
| + | char data[TAR_BLOCK_SIZE * 16]; |
| + | |
| + | /* |
| + | * Open the file for reading. |
| + | */ |
| + | fileFd = open (fileName, O_RDONLY); |
| + | |
| + | if (fileFd < 0) { |
| + | perror (fileName); |
| + | |
| + | return; |
| + | } |
| + | |
| + | /* |
| + | * Write out the header for the file. |
| + | */ |
| + | writeHeader (fileName, statbuf); |
| + | |
| + | /* |
| + | * Write the data blocks of the file. |
| + | * We must be careful to write the amount of data that the stat |
| + | * buffer indicated, even if the file has changed size. Otherwise |
| + | * the tar file will be incorrect. |
| + | */ |
| + | fullDataCount = statbuf->st_size; |
| + | sawEof = FALSE; |
| + | |
| + | while (fullDataCount > 0) { |
| + | /* |
| + | * Get the amount to write this iteration which is |
| + | * the minumum of the amount left to write and the |
| + | * buffer size. |
| */ | |
| - | fileFd = open(fileName, O_RDONLY); |
| - | |
| - | if (fileFd < 0) |
| - | { |
| - | perror(fileName); |
| + | dataCount = sizeof (data); |
| - | return; |
| - | } |
| + | if (dataCount > fullDataCount) |
| + | dataCount = (int) fullDataCount; |
| - | /* |
| - | * Write out the header for the file. |
| + | /* |
| + | * Read the data from the file if we haven't seen the |
| + | * end of file yet. |
| */ | |
| - | writeHeader(fileName, statbuf); |
| + | cc = 0; |
| - | /* |
| - | * Write the data blocks of the file. |
| - | * We must be careful to write the amount of data that the stat |
| - | * buffer indicated, even if the file has changed size. Otherwise |
| - | * the tar file will be incorrect. |
| - | */ |
| - | fullDataCount = statbuf->st_size; |
| - | sawEof = FALSE; |
| - | |
| - | while (fullDataCount > 0) |
| - | { |
| - | /* |
| - | * Get the amount to write this iteration which is |
| - | * the minumum of the amount left to write and the |
| - | * buffer size. |
| - | */ |
| - | dataCount = sizeof(data); |
| - | |
| - | if (dataCount > fullDataCount) |
| - | dataCount = (int) fullDataCount; |
| - | |
| - | /* |
| - | * Read the data from the file if we haven't seen the |
| - | * end of file yet. |
| - | */ |
| - | cc = 0; |
| - | |
| - | if (!sawEof) |
| - | { |
| - | cc = fullRead(fileFd, data, dataCount); |
| - | |
| - | if (cc < 0) |
| - | { |
| - | perror(fileName); |
| - | |
| - | (void) close(fileFd); |
| - | errorFlag = TRUE; |
| - | |
| - | return; |
| - | } |
| - | |
| - | /* |
| - | * If the file ended too soon, complain and set |
| - | * a flag so we will zero fill the rest of it. |
| - | */ |
| - | if (cc < dataCount) |
| - | { |
| - | fprintf(stderr, |
| - | "%s: Short read - zero filling", |
| - | fileName); |
| - | |
| - | sawEof = TRUE; |
| - | } |
| - | } |
| + | if (!sawEof) { |
| + | cc = fullRead (fileFd, data, dataCount); |
| - | /* |
| - | * Zero fill the rest of the data if necessary. |
| - | */ |
| - | if (cc < dataCount) |
| - | memset(data + cc, 0, dataCount - cc); |
| + | if (cc < 0) { |
| + | perror (fileName); |
| - | /* |
| - | * Write the buffer to the TAR file. |
| - | */ |
| - | writeTarBlock(data, dataCount); |
| + | (void) close (fileFd); |
| + | errorFlag = TRUE; |
| - | fullDataCount -= dataCount; |
| + | return; |
| + | } |
| + | |
| + | /* |
| + | * If the file ended too soon, complain and set |
| + | * a flag so we will zero fill the rest of it. |
| + | */ |
| + | if (cc < dataCount) { |
| + | fprintf (stderr, |
| + | "%s: Short read - zero filling", fileName); |
| + | |
| + | sawEof = TRUE; |
| + | } |
| } | |
| - | /* |
| - | * Close the file. |
| + | /* |
| + | * Zero fill the rest of the data if necessary. |
| + | */ |
| + | if (cc < dataCount) |
| + | memset (data + cc, 0, dataCount - cc); |
| + | |
| + | /* |
| + | * Write the buffer to the TAR file. |
| */ | |
| - | if ( (tostdoutFlag==FALSE) && close(fileFd) < 0) |
| - | fprintf(stderr, "%s: close: %s\n", fileName, strerror(errno)); |
| + | writeTarBlock (data, dataCount); |
| + | |
| + | fullDataCount -= dataCount; |
| + | } |
| + | |
| + | /* |
| + | * Close the file. |
| + | */ |
| + | if ((tostdoutFlag == FALSE) && close (fileFd) < 0) |
| + | fprintf (stderr, "%s: close: %s\n", fileName, strerror (errno)); |
| } | |
| /* | |
| * Save a directory and all of its files to the tar file. | |
| */ | |
| - | static void |
| - | saveDirectory(const char * dirName, const struct stat * statbuf) |
| + | static void saveDirectory (const char *dirName, const struct stat *statbuf) |
| { | |
| - | DIR * dir; |
| - | struct dirent * entry; |
| - | int needSlash; |
| - | char fullName[PATH_LEN]; |
| - | |
| - | /* |
| - | * Construct the directory name as used in the tar file by appending |
| - | * a slash character to it. |
| - | */ |
| - | strcpy(fullName, dirName); |
| - | strcat(fullName, "/"); |
| - | |
| - | /* |
| - | * Write out the header for the directory entry. |
| - | */ |
| - | writeHeader(fullName, statbuf); |
| - | |
| - | /* |
| - | * Open the directory. |
| - | */ |
| - | dir = opendir(dirName); |
| - | |
| - | if (dir == NULL) |
| - | { |
| - | fprintf(stderr, "Cannot read directory \"%s\": %s\n", |
| - | dirName, strerror(errno)); |
| - | |
| - | return; |
| + | DIR *dir; |
| + | struct dirent *entry; |
| + | int needSlash; |
| + | char fullName[PATH_LEN]; |
| + | |
| + | /* |
| + | * Construct the directory name as used in the tar file by appending |
| + | * a slash character to it. |
| + | */ |
| + | strcpy (fullName, dirName); |
| + | strcat (fullName, "/"); |
| + | |
| + | /* |
| + | * Write out the header for the directory entry. |
| + | */ |
| + | writeHeader (fullName, statbuf); |
| + | |
| + | /* |
| + | * Open the directory. |
| + | */ |
| + | dir = opendir (dirName); |
| + | |
| + | if (dir == NULL) { |
| + | fprintf (stderr, "Cannot read directory \"%s\": %s\n", |
| + | dirName, strerror (errno)); |
| + | |
| + | return; |
| + | } |
| + | |
| + | /* |
| + | * See if a slash is needed. |
| + | */ |
| + | needSlash = (*dirName && (dirName[strlen (dirName) - 1] != '/')); |
| + | |
| + | /* |
| + | * Read all of the directory entries and check them, |
| + | * except for the current and parent directory entries. |
| + | */ |
| + | while (!errorFlag && ((entry = readdir (dir)) != NULL)) { |
| + | if ((strcmp (entry->d_name, ".") == 0) || |
| + | (strcmp (entry->d_name, "..") == 0)) { |
| + | continue; |
| } | |
| - | /* |
| - | * See if a slash is needed. |
| + | /* |
| + | * Build the full path name to the file. |
| */ | |
| - | needSlash = (*dirName && (dirName[strlen(dirName) - 1] != '/')); |
| + | strcpy (fullName, dirName); |
| - | /* |
| - | * Read all of the directory entries and check them, |
| - | * except for the current and parent directory entries. |
| - | */ |
| - | while (!errorFlag && ((entry = readdir(dir)) != NULL)) |
| - | { |
| - | if ((strcmp(entry->d_name, ".") == 0) || |
| - | (strcmp(entry->d_name, "..") == 0)) |
| - | { |
| - | continue; |
| - | } |
| - | |
| - | /* |
| - | * Build the full path name to the file. |
| - | */ |
| - | strcpy(fullName, dirName); |
| + | if (needSlash) |
| + | strcat (fullName, "/"); |
| - | if (needSlash) |
| - | strcat(fullName, "/"); |
| + | strcat (fullName, entry->d_name); |
| - | strcat(fullName, entry->d_name); |
| - | |
| - | /* |
| - | * Write this file to the tar file, noticing whether or not |
| - | * the file is a symbolic link. |
| - | */ |
| - | saveFile(fullName, TRUE); |
| - | } |
| - | |
| - | /* |
| - | * All done, close the directory. |
| + | /* |
| + | * Write this file to the tar file, noticing whether or not |
| + | * the file is a symbolic link. |
| */ | |
| - | closedir(dir); |
| + | saveFile (fullName, TRUE); |
| + | } |
| + | |
| + | /* |
| + | * All done, close the directory. |
| + | */ |
| + | closedir (dir); |
| } | |
| @@ -970,55 +913,54 @@ saveDirectory(const char * dirName, const struct stat * statbuf) | |
| * Write a tar header for the specified file name and status. | |
| * It is assumed that the file name fits. | |
| */ | |
| - | static void |
| - | writeHeader(const char * fileName, const struct stat * statbuf) |
| + | static void writeHeader (const char *fileName, const struct stat *statbuf) |
| { | |
| - | long checkSum; |
| - | const unsigned char * cp; |
| - | int len; |
| - | TarHeader header; |
| - | |
| - | /* |
| - | * Zero the header block in preparation for filling it in. |
| - | */ |
| - | memset((char *) &header, 0, sizeof(header)); |
| - | |
| - | /* |
| - | * Fill in the header. |
| - | */ |
| - | strcpy(header.name, fileName); |
| - | |
| - | strncpy(header.magic, TAR_MAGIC, sizeof(header.magic)); |
| - | strncpy(header.version, TAR_VERSION, sizeof(header.version)); |
| - | |
| - | putOctal(header.mode, sizeof(header.mode), statbuf->st_mode & 0777); |
| - | putOctal(header.uid, sizeof(header.uid), statbuf->st_uid); |
| - | putOctal(header.gid, sizeof(header.gid), statbuf->st_gid); |
| - | putOctal(header.size, sizeof(header.size), statbuf->st_size); |
| - | putOctal(header.mtime, sizeof(header.mtime), statbuf->st_mtime); |
| - | |
| - | header.typeFlag = TAR_TYPE_REGULAR; |
| - | |
| - | /* |
| - | * Calculate and store the checksum. |
| - | * This is the sum of all of the bytes of the header, |
| - | * with the checksum field itself treated as blanks. |
| - | */ |
| - | memset(header.checkSum, ' ', sizeof(header.checkSum)); |
| - | |
| - | cp = (const unsigned char *) &header; |
| - | len = sizeof(header); |
| - | checkSum = 0; |
| - | |
| - | while (len-- > 0) |
| - | checkSum += *cp++; |
| - | |
| - | putOctal(header.checkSum, sizeof(header.checkSum), checkSum); |
| - | |
| - | /* |
| - | * Write the tar header. |
| - | */ |
| - | writeTarBlock((const char *) &header, sizeof(header)); |
| + | long checkSum; |
| + | const unsigned char *cp; |
| + | int len; |
| + | TarHeader header; |
| + | |
| + | /* |
| + | * Zero the header block in preparation for filling it in. |
| + | */ |
| + | memset ((char *) &header, 0, sizeof (header)); |
| + | |
| + | /* |
| + | * Fill in the header. |
| + | */ |
| + | strcpy (header.name, fileName); |
| + | |
| + | strncpy (header.magic, TAR_MAGIC, sizeof (header.magic)); |
| + | strncpy (header.version, TAR_VERSION, sizeof (header.version)); |
| + | |
| + | putOctal (header.mode, sizeof (header.mode), statbuf->st_mode & 0777); |
| + | putOctal (header.uid, sizeof (header.uid), statbuf->st_uid); |
| + | putOctal (header.gid, sizeof (header.gid), statbuf->st_gid); |
| + | putOctal (header.size, sizeof (header.size), statbuf->st_size); |
| + | putOctal (header.mtime, sizeof (header.mtime), statbuf->st_mtime); |
| + | |
| + | header.typeFlag = TAR_TYPE_REGULAR; |
| + | |
| + | /* |
| + | * Calculate and store the checksum. |
| + | * This is the sum of all of the bytes of the header, |
| + | * with the checksum field itself treated as blanks. |
| + | */ |
| + | memset (header.checkSum, ' ', sizeof (header.checkSum)); |
| + | |
| + | cp = (const unsigned char *) &header; |
| + | len = sizeof (header); |
| + | checkSum = 0; |
| + | |
| + | while (len-- > 0) |
| + | checkSum += *cp++; |
| + | |
| + | putOctal (header.checkSum, sizeof (header.checkSum), checkSum); |
| + | |
| + | /* |
| + | * Write the tar header. |
| + | */ |
| + | writeTarBlock ((const char *) &header, sizeof (header)); |
| } | |
| @@ -1027,59 +969,56 @@ writeHeader(const char * fileName, const struct stat * statbuf) | |
| * The data is always padded out to a multiple of TAR_BLOCK_SIZE. | |
| * The errorFlag static variable is set on an error. | |
| */ | |
| - | static void |
| - | writeTarBlock(const char * buf, int len) |
| + | static void writeTarBlock (const char *buf, int len) |
| { | |
| - | int partialLength; |
| - | int completeLength; |
| - | char fullBlock[TAR_BLOCK_SIZE]; |
| - | |
| - | /* |
| - | * If we had a write error before, then do nothing more. |
| - | */ |
| - | if (errorFlag) |
| - | return; |
| - | |
| - | /* |
| - | * Get the amount of complete and partial blocks. |
| - | */ |
| - | partialLength = len % TAR_BLOCK_SIZE; |
| - | completeLength = len - partialLength; |
| - | |
| - | /* |
| - | * Write all of the complete blocks. |
| - | */ |
| - | if ((completeLength > 0) && !fullWrite(tarFd, buf, completeLength)) |
| - | { |
| - | perror(tarName); |
| - | |
| - | errorFlag = TRUE; |
| - | |
| - | return; |
| - | } |
| - | |
| - | /* |
| - | * If there are no partial blocks left, we are done. |
| - | */ |
| - | if (partialLength == 0) |
| - | return; |
| - | |
| - | /* |
| - | * Copy the partial data into a complete block, and pad the rest |
| - | * of it with zeroes. |
| - | */ |
| - | memcpy(fullBlock, buf + completeLength, partialLength); |
| - | memset(fullBlock + partialLength, 0, TAR_BLOCK_SIZE - partialLength); |
| - | |
| - | /* |
| - | * Write the last complete block. |
| - | */ |
| - | if (!fullWrite(tarFd, fullBlock, TAR_BLOCK_SIZE)) |
| - | { |
| - | perror(tarName); |
| - | |
| - | errorFlag = TRUE; |
| - | } |
| + | int partialLength; |
| + | int completeLength; |
| + | char fullBlock[TAR_BLOCK_SIZE]; |
| + | |
| + | /* |
| + | * If we had a write error before, then do nothing more. |
| + | */ |
| + | if (errorFlag) |
| + | return; |
| + | |
| + | /* |
| + | * Get the amount of complete and partial blocks. |
| + | */ |
| + | partialLength = len % TAR_BLOCK_SIZE; |
| + | completeLength = len - partialLength; |
| + | |
| + | /* |
| + | * Write all of the complete blocks. |
| + | */ |
| + | if ((completeLength > 0) && !fullWrite (tarFd, buf, completeLength)) { |
| + | perror (tarName); |
| + | |
| + | errorFlag = TRUE; |
| + | |
| + | return; |
| + | } |
| + | |
| + | /* |
| + | * If there are no partial blocks left, we are done. |
| + | */ |
| + | if (partialLength == 0) |
| + | return; |
| + | |
| + | /* |
| + | * Copy the partial data into a complete block, and pad the rest |
| + | * of it with zeroes. |
| + | */ |
| + | memcpy (fullBlock, buf + completeLength, partialLength); |
| + | memset (fullBlock + partialLength, 0, TAR_BLOCK_SIZE - partialLength); |
| + | |
| + | /* |
| + | * Write the last complete block. |
| + | */ |
| + | if (!fullWrite (tarFd, fullBlock, TAR_BLOCK_SIZE)) { |
| + | perror (tarName); |
| + | |
| + | errorFlag = TRUE; |
| + | } |
| } | |
| @@ -1089,29 +1028,27 @@ writeTarBlock(const char * buf, int len) | |
| * 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) |
| + | static void createPath (const char *name, int mode) |
| { | |
| - | char * cp; |
| - | char * cpOld; |
| - | char buf[TAR_NAME_SIZE]; |
| + | char *cp; |
| + | char *cpOld; |
| + | char buf[TAR_NAME_SIZE]; |
| - | strcpy(buf, name); |
| + | strcpy (buf, name); |
| - | cp = strchr(buf, '/'); |
| + | cp = strchr (buf, '/'); |
| - | while (cp) |
| - | { |
| - | cpOld = cp; |
| - | cp = strchr(cp + 1, '/'); |
| + | while (cp) { |
| + | cpOld = cp; |
| + | cp = strchr (cp + 1, '/'); |
| - | *cpOld = '\0'; |
| + | *cpOld = '\0'; |
| - | if (mkdir(buf, cp ? 0777 : mode) == 0) |
| - | printf("Directory \"%s\" created\n", buf); |
| + | if (mkdir (buf, cp ? 0777 : mode) == 0) |
| + | printf ("Directory \"%s\" created\n", buf); |
| - | *cpOld = '/'; |
| - | } |
| + | *cpOld = '/'; |
| + | } |
| } | |
| @@ -1120,38 +1057,34 @@ createPath(const char * name, int mode) | |
| * spaces on both sides of the number and with an optional null character | |
| * at the end. Returns -1 on an illegal format. | |
| */ | |
| - | static long |
| - | getOctal(const char * cp, int len) |
| + | static long getOctal (const char *cp, int len) |
| { | |
| - | long val; |
| + | long val; |
| - | while ((len > 0) && (*cp == ' ')) |
| - | { |
| - | cp++; |
| - | len--; |
| - | } |
| + | while ((len > 0) && (*cp == ' ')) { |
| + | cp++; |
| + | len--; |
| + | } |
| - | if ((len == 0) || !isOctal(*cp)) |
| - | return -1; |
| + | if ((len == 0) || !isOctal (*cp)) |
| + | return -1; |
| - | val = 0; |
| + | val = 0; |
| - | while ((len > 0) && isOctal(*cp)) |
| - | { |
| - | val = val * 8 + *cp++ - '0'; |
| - | len--; |
| - | } |
| + | while ((len > 0) && isOctal (*cp)) { |
| + | val = val * 8 + *cp++ - '0'; |
| + | len--; |
| + | } |
| - | while ((len > 0) && (*cp == ' ')) |
| - | { |
| - | cp++; |
| - | len--; |
| - | } |
| + | while ((len > 0) && (*cp == ' ')) { |
| + | cp++; |
| + | len--; |
| + | } |
| - | if ((len > 0) && *cp) |
| - | return -1; |
| + | if ((len > 0) && *cp) |
| + | return -1; |
| - | return val; |
| + | return val; |
| } | |
| @@ -1160,50 +1093,48 @@ getOctal(const char * cp, int len) | |
| * The number is zero and space padded and possibly null padded. | |
| * Returns TRUE if successful. | |
| */ | |
| - | static int |
| - | putOctal(char * cp, int len, long value) |
| + | static int putOctal (char *cp, int len, long value) |
| { | |
| - | int tempLength; |
| - | char * tempString; |
| - | char tempBuffer[32]; |
| - | |
| - | /* |
| - | * Create a string of the specified length with an initial space, |
| - | * leading zeroes and the octal number, and a trailing null. |
| - | */ |
| - | tempString = tempBuffer; |
| - | |
| - | sprintf(tempString, " %0*lo", len - 2, value); |
| - | |
| - | tempLength = strlen(tempString) + 1; |
| - | |
| - | /* |
| - | * If the string is too large, suppress the leading space. |
| - | */ |
| - | if (tempLength > len) |
| - | { |
| - | tempLength--; |
| - | tempString++; |
| - | } |
| - | |
| - | /* |
| - | * If the string is still too large, suppress the trailing null. |
| - | */ |
| - | if (tempLength > len) |
| - | tempLength--; |
| + | int tempLength; |
| + | char *tempString; |
| + | char tempBuffer[32]; |
| + | |
| + | /* |
| + | * Create a string of the specified length with an initial space, |
| + | * leading zeroes and the octal number, and a trailing null. |
| + | */ |
| + | tempString = tempBuffer; |
| + | |
| + | sprintf (tempString, " %0*lo", len - 2, value); |
| + | |
| + | tempLength = strlen (tempString) + 1; |
| + | |
| + | /* |
| + | * If the string is too large, suppress the leading space. |
| + | */ |
| + | if (tempLength > len) { |
| + | tempLength--; |
| + | tempString++; |
| + | } |
| + | |
| + | /* |
| + | * If the string is still too large, suppress the trailing null. |
| + | */ |
| + | if (tempLength > len) |
| + | tempLength--; |
| + | |
| + | /* |
| + | * If the string is still too large, fail. |
| + | */ |
| + | if (tempLength > len) |
| + | return FALSE; |
| - | /* |
| - | * If the string is still too large, fail. |
| - | */ |
| - | if (tempLength > len) |
| - | return FALSE; |
| + | /* |
| + | * Copy the string to the field. |
| + | */ |
| + | memcpy (cp, tempString, len); |
| - | /* |
| - | * Copy the string to the field. |
| - | */ |
| - | memcpy(cp, tempString, len); |
| - | |
| - | return TRUE; |
| + | return TRUE; |
| } | |
| @@ -1213,48 +1144,43 @@ putOctal(char * cp, int len, long value) | |
| * Returns TRUE if the file is selected. | |
| */ | |
| static int | |
| - | wantFileName(const char * fileName, int fileCount, char ** fileTable) |
| + | wantFileName (const char *fileName, int fileCount, char **fileTable) |
| { | |
| - | const char * pathName; |
| - | int fileLength; |
| - | int pathLength; |
| - | |
| - | /* |
| - | * If there are no files in the list, then the file is wanted. |
| - | */ |
| - | if (fileCount == 0) |
| - | return TRUE; |
| + | const char *pathName; |
| + | int fileLength; |
| + | int pathLength; |
| + | |
| + | /* |
| + | * If there are no files in the list, then the file is wanted. |
| + | */ |
| + | if (fileCount == 0) |
| + | return TRUE; |
| - | fileLength = strlen(fileName); |
| + | fileLength = strlen (fileName); |
| - | /* |
| - | * Check each of the test paths. |
| - | */ |
| - | while (fileCount-- > 0) |
| - | { |
| - | pathName = *fileTable++; |
| + | /* |
| + | * Check each of the test paths. |
| + | */ |
| + | while (fileCount-- > 0) { |
| + | pathName = *fileTable++; |
| - | pathLength = strlen(pathName); |
| + | pathLength = strlen (pathName); |
| - | if (fileLength < pathLength) |
| - | continue; |
| + | if (fileLength < pathLength) |
| + | continue; |
| - | if (memcmp(fileName, pathName, pathLength) != 0) |
| - | continue; |
| + | if (memcmp (fileName, pathName, pathLength) != 0) |
| + | continue; |
| - | if ((fileLength == pathLength) || |
| - | (fileName[pathLength] == '/')) |
| - | { |
| - | return TRUE; |
| - | } |
| + | if ((fileLength == pathLength) || (fileName[pathLength] == '/')) { |
| + | return TRUE; |
| } | |
| + | } |
| - | return FALSE; |
| + | return FALSE; |
| } | |
| #endif | |
| /* END CODE */ | |
| - | |
| - | |
| @@ -16,7 +16,7 @@ | |
| //#define BB_DESCEND | |
| #define BB_DF | |
| #define BB_DMESG | |
| - | //#define BB_DUTMP |
| + | #define BB_DUTMP |
| //#define BB_DYADIC | |
| #define BB_FALSE | |
| //#define BB_FDFLUSH | |
| @@ -24,7 +24,7 @@ | |
| #define BB_GREP | |
| ////#define BB_HALT | |
| //#define BB_INIT | |
| - | //#define BB_KILL |
| + | #define BB_KILL |
| ////#define BB_LENGTH | |
| //#define BB_LN | |
| //#define BB_LOADKMAP | |
| @@ -44,10 +44,10 @@ | |
| //#define BB_POSTPROCESS | |
| //#define BB_PRINTF | |
| #define BB_PWD | |
| - | //#define BB_REBOOT |
| + | #define BB_REBOOT |
| //#define BB_RM | |
| //#define BB_RMDIR | |
| - | //#define BB_SLEEP |
| + | #define BB_SLEEP |
| ////#define BB_SWAPOFF | |
| //#define BB_SWAPON | |
| //#define BB_SYNC | |
| @@ -22,15 +22,27 @@ | |
| #include "internal.h" | |
| #include <stdio.h> | |
| - | const char cat_usage[] = "[file ...]"; |
| - | extern int cat_more_main(int argc, char **argv) |
| + | static void print_file( FILE *file) |
| { | |
| int c; | |
| - | FILE *file = stdin; |
| + | while ((c = getc(file)) != EOF) |
| + | putc(c, stdout); |
| + | fclose(file); |
| + | fflush(stdout); |
| + | } |
| + | |
| + | extern int cat_more_main(int argc, char **argv) |
| + | { |
| + | FILE *file; |
| + | |
| + | if (argc==1) { |
| + | print_file( stdin); |
| + | exit( TRUE); |
| + | } |
| - | if ( (argc < 2) || (**(argv+1) == '-') ) { |
| - | fprintf(stderr, "Usage: %s %s", *argv, cat_usage); |
| + | if ( **(argv+1) == '-' ) { |
| + | fprintf(stderr, "Usage: cat [file ...]\n"); |
| exit(FALSE); | |
| } | |
| argc--; | |
| @@ -42,11 +54,7 @@ extern int cat_more_main(int argc, char **argv) | |
| perror(*argv); | |
| exit(FALSE); | |
| } | |
| - | while ((c = getc(file)) != EOF) |
| - | putc(c, stdout); |
| - | fclose(file); |
| - | fflush(stdout); |
| - | |
| + | print_file( file); |
| argc--; | |
| argv++; | |
| } | |
| @@ -22,15 +22,27 @@ | |
| #include "internal.h" | |
| #include <stdio.h> | |
| - | const char cat_usage[] = "[file ...]"; |
| - | extern int cat_more_main(int argc, char **argv) |
| + | static void print_file( FILE *file) |
| { | |
| int c; | |
| - | FILE *file = stdin; |
| + | while ((c = getc(file)) != EOF) |
| + | putc(c, stdout); |
| + | fclose(file); |
| + | fflush(stdout); |
| + | } |
| + | |
| + | extern int cat_more_main(int argc, char **argv) |
| + | { |
| + | FILE *file; |
| + | |
| + | if (argc==1) { |
| + | print_file( stdin); |
| + | exit( TRUE); |
| + | } |
| - | if ( (argc < 2) || (**(argv+1) == '-') ) { |
| - | fprintf(stderr, "Usage: %s %s", *argv, cat_usage); |
| + | if ( **(argv+1) == '-' ) { |
| + | fprintf(stderr, "Usage: cat [file ...]\n"); |
| exit(FALSE); | |
| } | |
| argc--; | |
| @@ -42,11 +54,7 @@ extern int cat_more_main(int argc, char **argv) | |
| perror(*argv); | |
| exit(FALSE); | |
| } | |
| - | while ((c = getc(file)) != EOF) |
| - | putc(c, stdout); |
| - | fclose(file); |
| - | fflush(stdout); |
| - | |
| + | print_file( file); |
| argc--; | |
| argv++; | |
| } | |
| @@ -6,302 +6,211 @@ | |
| * The "dd" command, originally taken from sash. | |
| * | |
| * Permission to distribute this code under the GPL has been granted. | |
| - | * Majorly modified, and bugs fixed for busybox by Erik Andersen <[email protected]> <[email protected]> |
| + | * Mostly rewritten and bugs fixed for busybox by Erik Andersen <[email protected]> |
| */ | |
| #include "internal.h" | |
| - | #ifdef BB_DD |
| + | #include <stdio.h> |
| + | #include <fcntl.h> |
| + | #include <errno.h> |
| - | const char dd_usage[] = |
| - | "Copy a file, converting and formatting according to options\n\ |
| + | const char dd_usage[] = |
| + | "Copy a file, converting and formatting according to options\n\ |
| \n\ | |
| usage: [if=name] [of=name] [bs=n] [count=n]\n\ | |
| \tif=FILE\tread from FILE instead of stdin\n\ | |
| \tof=FILE\twrite to FILE instead of stout\n\ | |
| \tbs=n\tread and write N bytes at a time\n\ | |
| \tcount=n\tcopy only n input blocks\n\ | |
| + | \tskip=n\tskip n input blocks\n\ |
| \n\ | |
| BYTES may be suffixed: by k for x1024, b for x512, and w for x2.\n"; | |
| - | #include <stdio.h> |
| - | #include <dirent.h> |
| - | #include <errno.h> |
| - | #include <fcntl.h> |
| - | #include <signal.h> |
| - | #include <time.h> |
| - | |
| - | |
| - | #define PAR_NONE 0 |
| - | #define PAR_IF 1 |
| - | #define PAR_OF 2 |
| - | #define PAR_BS 3 |
| - | #define PAR_COUNT 4 |
| - | typedef struct |
| + | /* |
| + | * Read a number with a possible multiplier. |
| + | * Returns -1 if the number format is illegal. |
| + | */ |
| + | static long getNum (const char *cp) |
| { | |
| - | const char * name; |
| - | int value; |
| - | } PARAM; |
| + | long value; |
| + | if (!isDecimal (*cp)) |
| + | return -1; |
| - | static const PARAM params[] = |
| - | { |
| - | {"if", PAR_IF}, |
| - | {"of", PAR_OF}, |
| - | {"bs", PAR_BS}, |
| - | {"count", PAR_COUNT}, |
| - | {NULL, PAR_NONE} |
| - | }; |
| - | |
| + | value = 0; |
| - | static long getNum(const char * cp); |
| + | while (isDecimal (*cp)) |
| + | value = value * 10 + *cp++ - '0'; |
| - | extern int |
| - | dd_main (int argc, char **argv) |
| - | { |
| - | const char * str; |
| - | const PARAM * par; |
| - | const char * inFile; |
| - | const char * outFile; |
| - | char * cp; |
| - | int inFd; |
| - | int outFd; |
| - | int inCc=0; |
| - | int outCc; |
| - | int blockSize; |
| - | long count; |
| - | long intotal; |
| - | long outTotal; |
| - | unsigned char* buf; |
| - | unsigned char localBuf[BUF_SIZE]; |
| - | |
| - | inFile = NULL; |
| - | outFile = NULL; |
| - | blockSize = 512; |
| - | count = 1; |
| - | |
| - | |
| - | while (--argc > 0) |
| - | { |
| - | str = *++argv; |
| - | cp = strchr(str, '='); |
| - | |
| - | if (cp == NULL) |
| - | { |
| - | fprintf(stderr, "Bad dd argument\n"); |
| - | goto usage; |
| - | } |
| - | |
| - | *cp++ = '\0'; |
| - | |
| - | for (par = params; par->name; par++) |
| - | { |
| - | if (strcmp(str, par->name) == 0) |
| - | break; |
| - | } |
| - | |
| - | switch (par->value) |
| - | { |
| - | case PAR_IF: |
| - | if (inFile) |
| - | { |
| - | fprintf(stderr, "Multiple input files illegal\n"); |
| - | goto usage; |
| - | } |
| - | |
| - | //fprintf(stderr, "if=%s\n", cp); |
| - | inFile = cp; |
| - | break; |
| - | |
| - | case PAR_OF: |
| - | if (outFile) |
| - | { |
| - | fprintf(stderr, "Multiple output files illegal\n"); |
| - | goto usage; |
| - | } |
| - | |
| - | //fprintf(stderr, "of=%s\n", cp); |
| - | outFile = cp; |
| - | break; |
| - | |
| - | case PAR_BS: |
| - | blockSize = getNum(cp); |
| - | //fprintf(stderr, "bs=%d\n", blockSize); |
| - | |
| - | if (blockSize <= 0) |
| - | { |
| - | fprintf(stderr, "Bad block size value\n"); |
| - | goto usage; |
| - | } |
| - | |
| - | break; |
| - | |
| - | case PAR_COUNT: |
| - | count = getNum(cp); |
| - | //fprintf(stderr, "count=%ld\n", count); |
| - | |
| - | if (count < 0) |
| - | { |
| - | fprintf(stderr, "Bad count value\n"); |
| - | goto usage; |
| - | } |
| - | |
| - | break; |
| - | |
| - | default: |
| - | goto usage; |
| - | } |
| - | } |
| + | switch (*cp++) { |
| + | case 'k': |
| + | value *= 1024; |
| + | break; |
| - | buf = localBuf; |
| + | case 'b': |
| + | value *= 512; |
| + | break; |
| - | if (blockSize > sizeof(localBuf)) |
| - | { |
| - | buf = malloc(blockSize); |
| + | case 'w': |
| + | value *= 2; |
| + | break; |
| - | if (buf == NULL) |
| - | { |
| - | fprintf(stderr, "Cannot allocate buffer\n"); |
| - | return 1; |
| - | } |
| - | } |
| + | case '\0': |
| + | return value; |
| - | intotal = 0; |
| - | outTotal = 0; |
| + | default: |
| + | return -1; |
| + | } |
| - | if (inFile == NULL) |
| - | inFd = STDIN; |
| - | else |
| - | inFd = open(inFile, 0); |
| + | if (*cp) |
| + | return -1; |
| - | if (inFd < 0) |
| - | { |
| - | perror(inFile); |
| + | return value; |
| + | } |
| - | if (buf != localBuf) |
| - | free(buf); |
| - | return 1; |
| + | extern int dd_main (int argc, char **argv) |
| + | { |
| + | const char *inFile; |
| + | const char *outFile; |
| + | char *cp; |
| + | int inFd; |
| + | int outFd; |
| + | int inCc = 0; |
| + | int outCc; |
| + | int skipBlocks; |
| + | int blockSize; |
| + | long count; |
| + | long intotal; |
| + | long outTotal; |
| + | unsigned char *buf; |
| + | |
| + | inFile = NULL; |
| + | outFile = NULL; |
| + | blockSize = 512; |
| + | skipBlocks = 0; |
| + | count = 1; |
| + | |
| + | |
| + | argc--; |
| + | argv++; |
| + | |
| + | /* Parse any options */ |
| + | while (argc) { |
| + | if (inFile == NULL && (strncmp("if", *argv, 2) == 0)) |
| + | inFile=*argv; |
| + | else if (outFile == NULL && (strncmp("of", *argv, 2) == 0)) |
| + | outFile=*argv; |
| + | else if (strncmp("count", *argv, 5) == 0) { |
| + | count = getNum (*argv); |
| + | if (count <= 0) { |
| + | fprintf (stderr, "Bad count value %ld\n", count); |
| + | goto usage; |
| + | } |
| } | |
| - | |
| - | if (outFile == NULL) |
| - | outFd = STDOUT; |
| - | else |
| - | outFd = creat(outFile, 0666); |
| - | |
| - | if (outFd < 0) |
| - | { |
| - | perror(outFile); |
| - | close(inFd); |
| - | |
| - | if (buf != localBuf) |
| - | free(buf); |
| - | |
| - | return 1; |
| + | else if (strncmp("bs", *argv, 2) == 0) { |
| + | blockSize = getNum(*argv); |
| + | if (blockSize <= 0) { |
| + | fprintf (stderr, "Bad block size value %d\n", blockSize); |
| + | goto usage; |
| + | } |
| } | |
| + | else if (strncmp("skip", *argv, 4) == 0) { |
| + | skipBlocks = atoi( *argv); |
| + | if (skipBlocks <= 0) { |
| + | fprintf (stderr, "Bad skip value %d\n", skipBlocks); |
| + | goto usage; |
| + | } |
| - | while ( outTotal < count*blockSize ) |
| - | { |
| - | inCc = read(inFd, buf, blockSize); |
| - | if (inCc < 0) { |
| - | perror(inFile); |
| - | goto cleanup; |
| - | } |
| - | //fprintf(stderr, "read in =%d\n", inCc); |
| - | intotal += inCc; |
| - | cp = buf; |
| - | |
| - | |
| - | while ( intotal > outTotal ) |
| - | { |
| - | if (outTotal+inCc > count*blockSize) |
| - | inCc=count*blockSize-outTotal; |
| - | outCc = write(outFd, cp, inCc); |
| - | if (outCc < 0) |
| - | { |
| - | perror(outFile); |
| - | goto cleanup; |
| - | } |
| - | //fprintf(stderr, "wrote out =%d\n", outCc); |
| - | |
| - | inCc -= outCc; |
| - | cp += outCc; |
| - | outTotal += outCc; |
| - | //fprintf(stderr, "outTotal=%ld\n", outTotal); |
| - | } |
| } | |
| + | else { |
| + | fprintf (stderr, "Got here. argv=%s\n", *argv); |
| + | goto usage; |
| - | if (inCc < 0) |
| - | perror(inFile); |
| - | |
| - | cleanup: |
| - | close(inFd); |
| - | |
| - | if (close(outFd) < 0) |
| - | perror(outFile); |
| - | |
| - | if (buf != localBuf) |
| - | free(buf); |
| - | |
| - | printf("%ld+%d records in\n", intotal / blockSize, |
| - | (intotal % blockSize) != 0); |
| - | |
| - | printf("%ld+%d records out\n", outTotal / blockSize, |
| - | (outTotal % blockSize) != 0); |
| - | return 0; |
| - | usage: |
| - | |
| - | fprintf(stderr, "%s", dd_usage); |
| - | return 1; |
| - | } |
| - | |
| - | |
| - | /* |
| - | * Read a number with a possible multiplier. |
| - | * Returns -1 if the number format is illegal. |
| - | */ |
| - | static long |
| - | getNum(const char * cp) |
| - | { |
| - | long value; |
| - | |
| - | if (!isDecimal(*cp)) |
| - | return -1; |
| - | |
| - | value = 0; |
| - | |
| - | while (isDecimal(*cp)) |
| - | value = value * 10 + *cp++ - '0'; |
| - | |
| - | switch (*cp++) |
| - | { |
| - | case 'k': |
| - | value *= 1024; |
| - | break; |
| - | |
| - | case 'b': |
| - | value *= 512; |
| - | break; |
| - | |
| - | case 'w': |
| - | value *= 2; |
| - | break; |
| + | argc--; |
| + | argv++; |
| + | } |
| + | } |
| + | if ( inFile == NULL || outFile == NULL) |
| + | goto usage; |
| + | |
| + | buf = malloc (blockSize); |
| + | if (buf == NULL) { |
| + | fprintf (stderr, "Cannot allocate buffer\n"); |
| + | return( FALSE); |
| + | } |
| + | |
| + | intotal = 0; |
| + | outTotal = 0; |
| + | |
| + | if (!inFile) |
| + | inFd = STDIN; |
| + | else |
| + | inFd = open (inFile, 0); |
| + | |
| + | if (inFd < 0) { |
| + | perror (inFile); |
| + | free (buf); |
| + | return( FALSE); |
| + | } |
| + | |
| + | if (!outFile) |
| + | outFd = STDOUT; |
| + | else |
| + | outFd = creat (outFile, 0666); |
| + | |
| + | if (outFd < 0) { |
| + | perror (outFile); |
| + | close (inFd); |
| + | free (buf); |
| + | return( FALSE); |
| + | } |
| + | |
| + | lseek(inFd, skipBlocks*blockSize, SEEK_SET); |
| + | while (outTotal < count * blockSize) { |
| + | inCc = read (inFd, buf, blockSize); |
| + | if (inCc < 0) { |
| + | perror (inFile); |
| + | goto cleanup; |
| + | } |
| + | intotal += inCc; |
| + | cp = buf; |
| + | |
| + | while (intotal > outTotal) { |
| + | if (outTotal + inCc > count * blockSize) |
| + | inCc = count * blockSize - outTotal; |
| + | outCc = write (outFd, cp, inCc); |
| + | if (outCc < 0) { |
| + | perror (outFile); |
| + | goto cleanup; |
| + | } |
| + | |
| + | inCc -= outCc; |
| + | cp += outCc; |
| + | outTotal += outCc; |
| + | } |
| + | } |
| - | case '\0': |
| - | return value; |
| + | if (inCc < 0) |
| + | perror (inFile); |
| - | default: |
| - | return -1; |
| - | } |
| + | cleanup: |
| + | close (inFd); |
| + | close (outFd); |
| + | free (buf); |
| - | if (*cp) |
| - | return -1; |
| + | printf ("%ld+%d records in\n", intotal / blockSize, |
| + | (intotal % blockSize) != 0); |
| + | printf ("%ld+%d records out\n", outTotal / blockSize, |
| + | (outTotal % blockSize) != 0); |
| + | exit( TRUE); |
| + | usage: |
| - | return value; |
| + | fprintf (stderr, "%s", dd_usage); |
| + | exit( FALSE); |
| } | |
| - | #endif |
| - | /* END CODE */ |
| @@ -1,12 +1,13 @@ | |
| #include "internal.h" | |
| #include <stdio.h> | |
| + | #include <dirent.h> |
| const char pwd_usage[] = "Print the current directory.\n"; | |
| extern int | |
| pwd_main(int argc, char * * argv) | |
| { | |
| - | char buf[1024]; |
| + | char buf[NAME_MAX]; |
| if ( getcwd(buf, sizeof(buf)) == NULL ) { | |
| perror("get working directory"); | |
| @@ -1,15 +1,20 @@ | |
| #include "internal.h" | |
| #include <stdio.h> | |
| - | const char sleep_usage[] = "sleep seconds\n" |
| - | "\n" |
| - | "\tPause program execution for the given number of seconds.\n"; |
| + | const char sleep_usage[] = " NUMBER\n" |
| + | "Pause for NUMBER seconds.\n"; |
| extern int | |
| - | sleep_main(struct FileInfo * i, int argc, char * * argv) |
| + | sleep_main(int argc, char * * argv) |
| { | |
| - | if ( sleep(atoi(argv[1])) != 0 ) |
| - | return -1; |
| - | else |
| - | return 0; |
| + | if ( (argc < 2) || (**(argv+1) == '-') ) { |
| + | fprintf(stderr, "Usage: %s %s", *argv, sleep_usage); |
| + | exit(FALSE); |
| + | } |
| + | |
| + | if ( sleep(atoi(*(++argv))) != 0 ) { |
| + | perror( "sleep"); |
| + | exit (FALSE); |
| + | } else |
| + | exit (TRUE); |
| } | |
| @@ -6,302 +6,211 @@ | |
| * The "dd" command, originally taken from sash. | |
| * | |
| * Permission to distribute this code under the GPL has been granted. | |
| - | * Majorly modified, and bugs fixed for busybox by Erik Andersen <[email protected]> <[email protected]> |
| + | * Mostly rewritten and bugs fixed for busybox by Erik Andersen <[email protected]> |
| */ | |
| #include "internal.h" | |
| - | #ifdef BB_DD |
| + | #include <stdio.h> |
| + | #include <fcntl.h> |
| + | #include <errno.h> |
| - | const char dd_usage[] = |
| - | "Copy a file, converting and formatting according to options\n\ |
| + | const char dd_usage[] = |
| + | "Copy a file, converting and formatting according to options\n\ |
| \n\ | |
| usage: [if=name] [of=name] [bs=n] [count=n]\n\ | |
| \tif=FILE\tread from FILE instead of stdin\n\ | |
| \tof=FILE\twrite to FILE instead of stout\n\ | |
| \tbs=n\tread and write N bytes at a time\n\ | |
| \tcount=n\tcopy only n input blocks\n\ | |
| + | \tskip=n\tskip n input blocks\n\ |
| \n\ | |
| BYTES may be suffixed: by k for x1024, b for x512, and w for x2.\n"; | |
| - | #include <stdio.h> |
| - | #include <dirent.h> |
| - | #include <errno.h> |
| - | #include <fcntl.h> |
| - | #include <signal.h> |
| - | #include <time.h> |
| - | |
| - | |
| - | #define PAR_NONE 0 |
| - | #define PAR_IF 1 |
| - | #define PAR_OF 2 |
| - | #define PAR_BS 3 |
| - | #define PAR_COUNT 4 |
| - | typedef struct |
| + | /* |
| + | * Read a number with a possible multiplier. |
| + | * Returns -1 if the number format is illegal. |
| + | */ |
| + | static long getNum (const char *cp) |
| { | |
| - | const char * name; |
| - | int value; |
| - | } PARAM; |
| + | long value; |
| + | if (!isDecimal (*cp)) |
| + | return -1; |
| - | static const PARAM params[] = |
| - | { |
| - | {"if", PAR_IF}, |
| - | {"of", PAR_OF}, |
| - | {"bs", PAR_BS}, |
| - | {"count", PAR_COUNT}, |
| - | {NULL, PAR_NONE} |
| - | }; |
| - | |
| + | value = 0; |
| - | static long getNum(const char * cp); |
| + | while (isDecimal (*cp)) |
| + | value = value * 10 + *cp++ - '0'; |
| - | extern int |
| - | dd_main (int argc, char **argv) |
| - | { |
| - | const char * str; |
| - | const PARAM * par; |
| - | const char * inFile; |
| - | const char * outFile; |
| - | char * cp; |
| - | int inFd; |
| - | int outFd; |
| - | int inCc=0; |
| - | int outCc; |
| - | int blockSize; |
| - | long count; |
| - | long intotal; |
| - | long outTotal; |
| - | unsigned char* buf; |
| - | unsigned char localBuf[BUF_SIZE]; |
| - | |
| - | inFile = NULL; |
| - | outFile = NULL; |
| - | blockSize = 512; |
| - | count = 1; |
| - | |
| - | |
| - | while (--argc > 0) |
| - | { |
| - | str = *++argv; |
| - | cp = strchr(str, '='); |
| - | |
| - | if (cp == NULL) |
| - | { |
| - | fprintf(stderr, "Bad dd argument\n"); |
| - | goto usage; |
| - | } |
| - | |
| - | *cp++ = '\0'; |
| - | |
| - | for (par = params; par->name; par++) |
| - | { |
| - | if (strcmp(str, par->name) == 0) |
| - | break; |
| - | } |
| - | |
| - | switch (par->value) |
| - | { |
| - | case PAR_IF: |
| - | if (inFile) |
| - | { |
| - | fprintf(stderr, "Multiple input files illegal\n"); |
| - | goto usage; |
| - | } |
| - | |
| - | //fprintf(stderr, "if=%s\n", cp); |
| - | inFile = cp; |
| - | break; |
| - | |
| - | case PAR_OF: |
| - | if (outFile) |
| - | { |
| - | fprintf(stderr, "Multiple output files illegal\n"); |
| - | goto usage; |
| - | } |
| - | |
| - | //fprintf(stderr, "of=%s\n", cp); |
| - | outFile = cp; |
| - | break; |
| - | |
| - | case PAR_BS: |
| - | blockSize = getNum(cp); |
| - | //fprintf(stderr, "bs=%d\n", blockSize); |
| - | |
| - | if (blockSize <= 0) |
| - | { |
| - | fprintf(stderr, "Bad block size value\n"); |
| - | goto usage; |
| - | } |
| - | |
| - | break; |
| - | |
| - | case PAR_COUNT: |
| - | count = getNum(cp); |
| - | //fprintf(stderr, "count=%ld\n", count); |
| - | |
| - | if (count < 0) |
| - | { |
| - | fprintf(stderr, "Bad count value\n"); |
| - | goto usage; |
| - | } |
| - | |
| - | break; |
| - | |
| - | default: |
| - | goto usage; |
| - | } |
| - | } |
| + | switch (*cp++) { |
| + | case 'k': |
| + | value *= 1024; |
| + | break; |
| - | buf = localBuf; |
| + | case 'b': |
| + | value *= 512; |
| + | break; |
| - | if (blockSize > sizeof(localBuf)) |
| - | { |
| - | buf = malloc(blockSize); |
| + | case 'w': |
| + | value *= 2; |
| + | break; |
| - | if (buf == NULL) |
| - | { |
| - | fprintf(stderr, "Cannot allocate buffer\n"); |
| - | return 1; |
| - | } |
| - | } |
| + | case '\0': |
| + | return value; |
| - | intotal = 0; |
| - | outTotal = 0; |
| + | default: |
| + | return -1; |
| + | } |
| - | if (inFile == NULL) |
| - | inFd = STDIN; |
| - | else |
| - | inFd = open(inFile, 0); |
| + | if (*cp) |
| + | return -1; |
| - | if (inFd < 0) |
| - | { |
| - | perror(inFile); |
| + | return value; |
| + | } |
| - | if (buf != localBuf) |
| - | free(buf); |
| - | return 1; |
| + | extern int dd_main (int argc, char **argv) |
| + | { |
| + | const char *inFile; |
| + | const char *outFile; |
| + | char *cp; |
| + | int inFd; |
| + | int outFd; |
| + | int inCc = 0; |
| + | int outCc; |
| + | int skipBlocks; |
| + | int blockSize; |
| + | long count; |
| + | long intotal; |
| + | long outTotal; |
| + | unsigned char *buf; |
| + | |
| + | inFile = NULL; |
| + | outFile = NULL; |
| + | blockSize = 512; |
| + | skipBlocks = 0; |
| + | count = 1; |
| + | |
| + | |
| + | argc--; |
| + | argv++; |
| + | |
| + | /* Parse any options */ |
| + | while (argc) { |
| + | if (inFile == NULL && (strncmp("if", *argv, 2) == 0)) |
| + | inFile=*argv; |
| + | else if (outFile == NULL && (strncmp("of", *argv, 2) == 0)) |
| + | outFile=*argv; |
| + | else if (strncmp("count", *argv, 5) == 0) { |
| + | count = getNum (*argv); |
| + | if (count <= 0) { |
| + | fprintf (stderr, "Bad count value %ld\n", count); |
| + | goto usage; |
| + | } |
| } | |
| - | |
| - | if (outFile == NULL) |
| - | outFd = STDOUT; |
| - | else |
| - | outFd = creat(outFile, 0666); |
| - | |
| - | if (outFd < 0) |
| - | { |
| - | perror(outFile); |
| - | close(inFd); |
| - | |
| - | if (buf != localBuf) |
| - | free(buf); |
| - | |
| - | return 1; |
| + | else if (strncmp("bs", *argv, 2) == 0) { |
| + | blockSize = getNum(*argv); |
| + | if (blockSize <= 0) { |
| + | fprintf (stderr, "Bad block size value %d\n", blockSize); |
| + | goto usage; |
| + | } |
| } | |
| + | else if (strncmp("skip", *argv, 4) == 0) { |
| + | skipBlocks = atoi( *argv); |
| + | if (skipBlocks <= 0) { |
| + | fprintf (stderr, "Bad skip value %d\n", skipBlocks); |
| + | goto usage; |
| + | } |
| - | while ( outTotal < count*blockSize ) |
| - | { |
| - | inCc = read(inFd, buf, blockSize); |
| - | if (inCc < 0) { |
| - | perror(inFile); |
| - | goto cleanup; |
| - | } |
| - | //fprintf(stderr, "read in =%d\n", inCc); |
| - | intotal += inCc; |
| - | cp = buf; |
| - | |
| - | |
| - | while ( intotal > outTotal ) |
| - | { |
| - | if (outTotal+inCc > count*blockSize) |
| - | inCc=count*blockSize-outTotal; |
| - | outCc = write(outFd, cp, inCc); |
| - | if (outCc < 0) |
| - | { |
| - | perror(outFile); |
| - | goto cleanup; |
| - | } |
| - | //fprintf(stderr, "wrote out =%d\n", outCc); |
| - | |
| - | inCc -= outCc; |
| - | cp += outCc; |
| - | outTotal += outCc; |
| - | //fprintf(stderr, "outTotal=%ld\n", outTotal); |
| - | } |
| } | |
| + | else { |
| + | fprintf (stderr, "Got here. argv=%s\n", *argv); |
| + | goto usage; |
| - | if (inCc < 0) |
| - | perror(inFile); |
| - | |
| - | cleanup: |
| - | close(inFd); |
| - | |
| - | if (close(outFd) < 0) |
| - | perror(outFile); |
| - | |
| - | if (buf != localBuf) |
| - | free(buf); |
| - | |
| - | printf("%ld+%d records in\n", intotal / blockSize, |
| - | (intotal % blockSize) != 0); |
| - | |
| - | printf("%ld+%d records out\n", outTotal / blockSize, |
| - | (outTotal % blockSize) != 0); |
| - | return 0; |
| - | usage: |
| - | |
| - | fprintf(stderr, "%s", dd_usage); |
| - | return 1; |
| - | } |
| - | |
| - | |
| - | /* |
| - | * Read a number with a possible multiplier. |
| - | * Returns -1 if the number format is illegal. |
| - | */ |
| - | static long |
| - | getNum(const char * cp) |
| - | { |
| - | long value; |
| - | |
| - | if (!isDecimal(*cp)) |
| - | return -1; |
| - | |
| - | value = 0; |
| - | |
| - | while (isDecimal(*cp)) |
| - | value = value * 10 + *cp++ - '0'; |
| - | |
| - | switch (*cp++) |
| - | { |
| - | case 'k': |
| - | value *= 1024; |
| - | break; |
| - | |
| - | case 'b': |
| - | value *= 512; |
| - | break; |
| - | |
| - | case 'w': |
| - | value *= 2; |
| - | break; |
| + | argc--; |
| + | argv++; |
| + | } |
| + | } |
| + | if ( inFile == NULL || outFile == NULL) |
| + | goto usage; |
| + | |
| + | buf = malloc (blockSize); |
| + | if (buf == NULL) { |
| + | fprintf (stderr, "Cannot allocate buffer\n"); |
| + | return( FALSE); |
| + | } |
| + | |
| + | intotal = 0; |
| + | outTotal = 0; |
| + | |
| + | if (!inFile) |
| + | inFd = STDIN; |
| + | else |
| + | inFd = open (inFile, 0); |
| + | |
| + | if (inFd < 0) { |
| + | perror (inFile); |
| + | free (buf); |
| + | return( FALSE); |
| + | } |
| + | |
| + | if (!outFile) |
| + | outFd = STDOUT; |
| + | else |
| + | outFd = creat (outFile, 0666); |
| + | |
| + | if (outFd < 0) { |
| + | perror (outFile); |
| + | close (inFd); |
| + | free (buf); |
| + | return( FALSE); |
| + | } |
| + | |
| + | lseek(inFd, skipBlocks*blockSize, SEEK_SET); |
| + | while (outTotal < count * blockSize) { |
| + | inCc = read (inFd, buf, blockSize); |
| + | if (inCc < 0) { |
| + | perror (inFile); |
| + | goto cleanup; |
| + | } |
| + | intotal += inCc; |
| + | cp = buf; |
| + | |
| + | while (intotal > outTotal) { |
| + | if (outTotal + inCc > count * blockSize) |
| + | inCc = count * blockSize - outTotal; |
| + | outCc = write (outFd, cp, inCc); |
| + | if (outCc < 0) { |
| + | perror (outFile); |
| + | goto cleanup; |
| + | } |
| + | |
| + | inCc -= outCc; |
| + | cp += outCc; |
| + | outTotal += outCc; |
| + | } |
| + | } |
| - | case '\0': |
| - | return value; |
| + | if (inCc < 0) |
| + | perror (inFile); |
| - | default: |
| - | return -1; |
| - | } |
| + | cleanup: |
| + | close (inFd); |
| + | close (outFd); |
| + | free (buf); |
| - | if (*cp) |
| - | return -1; |
| + | printf ("%ld+%d records in\n", intotal / blockSize, |
| + | (intotal % blockSize) != 0); |
| + | printf ("%ld+%d records out\n", outTotal / blockSize, |
| + | (outTotal % blockSize) != 0); |
| + | exit( TRUE); |
| + | usage: |
| - | return value; |
| + | fprintf (stderr, "%s", dd_usage); |
| + | exit( FALSE); |
| } | |
| - | #endif |
| - | /* END CODE */ |
| @@ -14,7 +14,6 @@ | |
| #include <linux/unistd.h> | |
| #include <stdio.h> | |
| - | #include <getopt.h> |
| #define __NR_klog __NR_syslog | |
| @@ -22,74 +21,78 @@ | |
| #include <sys/klog.h> | |
| #define klog klogctl | |
| #else | |
| - | static inline _syscall3(int,klog,int,type,char *,b,int,len) |
| - | #endif /* __GLIBC__ */ |
| + | static inline _syscall3 (int, klog, int, type, char *, b, int, len) |
| + | #endif /* __GLIBC__ */ |
| - | const char dmesg_usage[] = "dmesg"; |
| - | int |
| - | dmesg_main(int argc, char * * argv) |
| + | |
| + | static const char dmesg_usage[] = "dmesg [-c] [-n level]\n"; |
| + | |
| + | int dmesg_main (int argc, char **argv) |
| { | |
| - | char buf[4096]; |
| - | int i; |
| - | int n; |
| - | int c; |
| - | int level = 0; |
| - | int lastc; |
| - | int cmd = 3; |
| + | char buf[4096]; |
| + | int i; |
| + | int n; |
| + | int level = 0; |
| + | int lastc; |
| + | int cmd = 3; |
| - | while ((c = getopt( argc, argv, "cn:" )) != EOF) { |
| - | switch (c) { |
| - | case 'c': |
| - | cmd = 4; |
| - | break; |
| - | case 'n': |
| - | cmd = 8; |
| - | level = atoi(optarg); |
| - | break; |
| - | case '?': |
| - | default: |
| - | fprintf(stderr, "%s\n", dmesg_usage); |
| - | exit(1); |
| - | } |
| - | } |
| - | argc -= optind; |
| - | argv += optind; |
| - | |
| - | if (argc > 1) { |
| - | fprintf(stderr, "%s\n", dmesg_usage); |
| - | exit(1); |
| - | } |
| + | argc--; |
| + | argv++; |
| - | if (cmd == 8) { |
| - | n = klog( cmd, NULL, level ); |
| - | if (n < 0) { |
| - | perror( "klog" ); |
| - | exit( 1 ); |
| - | } |
| - | exit( 0 ); |
| - | } |
| + | /* Parse any options */ |
| + | while (argc && **argv == '-') { |
| + | while (*++(*argv)) |
| + | switch (**argv) { |
| + | case 'c': |
| + | cmd = 4; |
| + | break; |
| + | case 'n': |
| + | cmd = 8; |
| + | if (--argc == 0) |
| + | goto end; |
| + | level = atoi (*(++argv)); |
| + | --argc; |
| + | ++argv; |
| + | break; |
| + | default: |
| + | goto end; |
| + | } |
| + | } |
| - | n = klog( cmd, buf, sizeof( buf ) ); |
| - | if (n < 0) { |
| - | perror( "klog" ); |
| - | exit( 1 ); |
| - | } |
| + | if (cmd == 8) { |
| + | n = klog (cmd, NULL, level); |
| + | if (n < 0) { |
| + | perror ("klog"); |
| + | exit (FALSE); |
| + | } |
| + | exit (TRUE); |
| + | } |
| - | lastc = '\n'; |
| - | for (i = 0; i < n; i++) { |
| - | if ((i == 0 || buf[i - 1] == '\n') && buf[i] == '<') { |
| - | i++; |
| - | while (buf[i] >= '0' && buf[i] <= '9') |
| - | i++; |
| - | if (buf[i] == '>') |
| + | n = klog (cmd, buf, sizeof (buf)); |
| + | if (n < 0) { |
| + | perror ("klog"); |
| + | exit (FALSE); |
| + | } |
| + | |
| + | lastc = '\n'; |
| + | for (i = 0; i < n; i++) { |
| + | if ((i == 0 || buf[i - 1] == '\n') && buf[i] == '<') { |
| i++; | |
| - | } |
| - | lastc = buf[i]; |
| - | putchar( lastc ); |
| - | } |
| - | if (lastc != '\n') |
| - | putchar( '\n' ); |
| - | return 0; |
| + | while (buf[i] >= '0' && buf[i] <= '9') |
| + | i++; |
| + | if (buf[i] == '>') |
| + | i++; |
| + | } |
| + | lastc = buf[i]; |
| + | putchar (lastc); |
| + | } |
| + | if (lastc != '\n') |
| + | putchar ('\n'); |
| + | exit (TRUE); |
| + | |
| + | end: |
| + | fprintf (stderr, "Usage: %s\n", dmesg_usage); |
| + | exit (FALSE); |
| } | |
| @@ -9,39 +9,44 @@ | |
| * | |
| * made against libc6 | |
| */ | |
| - | |
| + | |
| #include "internal.h" | |
| #include <stdio.h> | |
| #include <utmp.h> | |
| - | const char dutmp_usage[] = "dutmp\n" |
| - | "\n" |
| - | "\tDump file or stdin utmp file format to stdout, pipe delimited.\n" |
| - | "\tdutmp /var/run/utmp\n"; |
| + | const char dutmp_usage[] = "dutmp\n" |
| + | "\n" |
| + | "\tDump file or stdin utmp file format to stdout, pipe delimited.\n" |
| + | "\tdutmp /var/run/utmp\n"; |
| - | extern int |
| - | dutmp_fn(const struct FileInfo * i) |
| + | extern int dutmp_fn (int argc, char **argv) |
| { | |
| - | FILE * f = stdin; |
| - | struct utmp * ut = (struct utmp *) malloc(sizeof(struct utmp) ); |
| - | |
| - | if ( i ) |
| - | if (! (f = fopen(i->source, "r"))) { |
| - | name_and_error(i->source); |
| - | return 1; |
| - | } |
| - | |
| - | while (fread (ut, 1, sizeof(struct utmp), f)) { |
| - | //printf("%d:%d:%s:%s:%s:%s:%d:%d:%ld:%ld:%ld:%x\n", |
| - | printf("%d|%d|%s|%s|%s|%s|%d|%d|%ld|%ld|%ld|%x\n", |
| - | ut->ut_type, ut->ut_pid, ut->ut_line, |
| - | ut->ut_id, ut->ut_user, ut->ut_host, |
| - | ut->ut_exit.e_termination, ut->ut_exit.e_exit, |
| - | ut->ut_session, |
| - | ut->ut_tv.tv_sec, ut->ut_tv.tv_usec, |
| - | ut->ut_addr); |
| - | } |
| - | |
| - | return 0; |
| + | FILE *f = stdin; |
| + | struct utmp ut; |
| + | |
| + | if ((argc < 2) || (**(argv + 1) == '-')) { |
| + | fprintf (stderr, "Usage: %s %s\n", *argv, dutmp_usage); |
| + | exit (FALSE); |
| + | } |
| + | |
| + | if ( **(++argv) == 0 ) { |
| + | f = fopen (*(++argv), "r"); |
| + | if (f < 0 ) { |
| + | perror (*argv); |
| + | exit (FALSE); |
| + | } |
| + | } |
| + | |
| + | while (fread (&ut, 1, sizeof (struct utmp), f)) { |
| + | // printf("%d:%d:%s:%s:%s:%s:%d:%d:%ld:%ld:%ld:%x\n", |
| + | printf ("%d|%d|%s|%s|%s|%s|%d|%d|%ld|%ld|%ld|%x\n", |
| + | ut.ut_type, ut.ut_pid, ut.ut_line, |
| + | ut.ut_id, ut.ut_user, ut.ut_host, |
| + | ut.ut_exit.e_termination, ut.ut_exit.e_exit, |
| + | ut.ut_session, |
| + | ut.ut_tv.tv_sec, ut.ut_tv.tv_usec, ut.ut_addr); |
| + | } |
| + | |
| + | exit (TRUE); |
| } | |
| @@ -11,7 +11,6 @@ | |
| */ | |
| #include "internal.h" | |
| - | #ifdef BB_GREP |
| #include <stdio.h> | |
| #include <dirent.h> | |
| @@ -31,7 +30,76 @@ const char grep_usage[] = | |
| - | static int search (const char *string, const char *word, int ignoreCase); |
| + | /* |
| + | * See if the specified word is found in the specified string. |
| + | */ |
| + | static int search (const char *string, const char *word, int ignoreCase) |
| + | { |
| + | const char *cp1; |
| + | const char *cp2; |
| + | int len; |
| + | int lowFirst; |
| + | int ch1; |
| + | int ch2; |
| + | |
| + | len = strlen (word); |
| + | |
| + | if (!ignoreCase) { |
| + | while (TRUE) { |
| + | string = strchr (string, word[0]); |
| + | |
| + | if (string == NULL) |
| + | return FALSE; |
| + | |
| + | if (memcmp (string, word, len) == 0) |
| + | return TRUE; |
| + | |
| + | string++; |
| + | } |
| + | } |
| + | |
| + | /* |
| + | * Here if we need to check case independence. |
| + | * Do the search by lower casing both strings. |
| + | */ |
| + | lowFirst = *word; |
| + | |
| + | if (isupper (lowFirst)) |
| + | lowFirst = tolower (lowFirst); |
| + | |
| + | while (TRUE) { |
| + | while (*string && (*string != lowFirst) && |
| + | (!isupper (*string) || (tolower (*string) != lowFirst))) { |
| + | string++; |
| + | } |
| + | |
| + | if (*string == '\0') |
| + | return FALSE; |
| + | |
| + | cp1 = string; |
| + | cp2 = word; |
| + | |
| + | do { |
| + | if (*cp2 == '\0') |
| + | return TRUE; |
| + | |
| + | ch1 = *cp1++; |
| + | |
| + | if (isupper (ch1)) |
| + | ch1 = tolower (ch1); |
| + | |
| + | ch2 = *cp2++; |
| + | |
| + | if (isupper (ch2)) |
| + | ch2 = tolower (ch2); |
| + | |
| + | } |
| + | while (ch1 == ch2); |
| + | |
| + | string++; |
| + | } |
| + | return (TRUE); |
| + | } |
| extern int grep_main (int argc, char **argv) | |
| @@ -122,76 +190,6 @@ extern int grep_main (int argc, char **argv) | |
| } | |
| - | /* |
| - | * See if the specified word is found in the specified string. |
| - | */ |
| - | static int search (const char *string, const char *word, int ignoreCase) |
| - | { |
| - | const char *cp1; |
| - | const char *cp2; |
| - | int len; |
| - | int lowFirst; |
| - | int ch1; |
| - | int ch2; |
| - | |
| - | len = strlen (word); |
| - | |
| - | if (!ignoreCase) { |
| - | while (TRUE) { |
| - | string = strchr (string, word[0]); |
| - | |
| - | if (string == NULL) |
| - | return FALSE; |
| - | |
| - | if (memcmp (string, word, len) == 0) |
| - | return TRUE; |
| - | |
| - | string++; |
| - | } |
| - | } |
| - | |
| - | /* |
| - | * Here if we need to check case independence. |
| - | * Do the search by lower casing both strings. |
| - | */ |
| - | lowFirst = *word; |
| - | |
| - | if (isupper (lowFirst)) |
| - | lowFirst = tolower (lowFirst); |
| - | |
| - | while (TRUE) { |
| - | while (*string && (*string != lowFirst) && |
| - | (!isupper (*string) || (tolower (*string) != lowFirst))) { |
| - | string++; |
| - | } |
| - | |
| - | if (*string == '\0') |
| - | return FALSE; |
| - | |
| - | cp1 = string; |
| - | cp2 = word; |
| - | |
| - | do { |
| - | if (*cp2 == '\0') |
| - | return TRUE; |
| - | |
| - | ch1 = *cp1++; |
| - | |
| - | if (isupper (ch1)) |
| - | ch1 = tolower (ch1); |
| - | |
| - | ch2 = *cp2++; |
| - | |
| - | if (isupper (ch2)) |
| - | ch2 = tolower (ch2); |
| - | |
| - | } |
| - | while (ch1 == ch2); |
| + | /* END CODE */ |
| - | string++; |
| - | } |
| - | return (TRUE); |
| - | } |
| - | #endif |
| - | /* END CODE */ |
| @@ -11,7 +11,6 @@ | |
| */ | |
| #include "internal.h" | |
| - | #ifdef BB_GREP |
| #include <stdio.h> | |
| #include <dirent.h> | |
| @@ -31,7 +30,76 @@ const char grep_usage[] = | |
| - | static int search (const char *string, const char *word, int ignoreCase); |
| + | /* |
| + | * See if the specified word is found in the specified string. |
| + | */ |
| + | static int search (const char *string, const char *word, int ignoreCase) |
| + | { |
| + | const char *cp1; |
| + | const char *cp2; |
| + | int len; |
| + | int lowFirst; |
| + | int ch1; |
| + | int ch2; |
| + | |
| + | len = strlen (word); |
| + | |
| + | if (!ignoreCase) { |
| + | while (TRUE) { |
| + | string = strchr (string, word[0]); |
| + | |
| + | if (string == NULL) |
| + | return FALSE; |
| + | |
| + | if (memcmp (string, word, len) == 0) |
| + | return TRUE; |
| + | |
| + | string++; |
| + | } |
| + | } |
| + | |
| + | /* |
| + | * Here if we need to check case independence. |
| + | * Do the search by lower casing both strings. |
| + | */ |
| + | lowFirst = *word; |
| + | |
| + | if (isupper (lowFirst)) |
| + | lowFirst = tolower (lowFirst); |
| + | |
| + | while (TRUE) { |
| + | while (*string && (*string != lowFirst) && |
| + | (!isupper (*string) || (tolower (*string) != lowFirst))) { |
| + | string++; |
| + | } |
| + | |
| + | if (*string == '\0') |
| + | return FALSE; |
| + | |
| + | cp1 = string; |
| + | cp2 = word; |
| + | |
| + | do { |
| + | if (*cp2 == '\0') |
| + | return TRUE; |
| + | |
| + | ch1 = *cp1++; |
| + | |
| + | if (isupper (ch1)) |
| + | ch1 = tolower (ch1); |
| + | |
| + | ch2 = *cp2++; |
| + | |
| + | if (isupper (ch2)) |
| + | ch2 = tolower (ch2); |
| + | |
| + | } |
| + | while (ch1 == ch2); |
| + | |
| + | string++; |
| + | } |
| + | return (TRUE); |
| + | } |
| extern int grep_main (int argc, char **argv) | |
| @@ -122,76 +190,6 @@ extern int grep_main (int argc, char **argv) | |
| } | |
| - | /* |
| - | * See if the specified word is found in the specified string. |
| - | */ |
| - | static int search (const char *string, const char *word, int ignoreCase) |
| - | { |
| - | const char *cp1; |
| - | const char *cp2; |
| - | int len; |
| - | int lowFirst; |
| - | int ch1; |
| - | int ch2; |
| - | |
| - | len = strlen (word); |
| - | |
| - | if (!ignoreCase) { |
| - | while (TRUE) { |
| - | string = strchr (string, word[0]); |
| - | |
| - | if (string == NULL) |
| - | return FALSE; |
| - | |
| - | if (memcmp (string, word, len) == 0) |
| - | return TRUE; |
| - | |
| - | string++; |
| - | } |
| - | } |
| - | |
| - | /* |
| - | * Here if we need to check case independence. |
| - | * Do the search by lower casing both strings. |
| - | */ |
| - | lowFirst = *word; |
| - | |
| - | if (isupper (lowFirst)) |
| - | lowFirst = tolower (lowFirst); |
| - | |
| - | while (TRUE) { |
| - | while (*string && (*string != lowFirst) && |
| - | (!isupper (*string) || (tolower (*string) != lowFirst))) { |
| - | string++; |
| - | } |
| - | |
| - | if (*string == '\0') |
| - | return FALSE; |
| - | |
| - | cp1 = string; |
| - | cp2 = word; |
| - | |
| - | do { |
| - | if (*cp2 == '\0') |
| - | return TRUE; |
| - | |
| - | ch1 = *cp1++; |
| - | |
| - | if (isupper (ch1)) |
| - | ch1 = tolower (ch1); |
| - | |
| - | ch2 = *cp2++; |
| - | |
| - | if (isupper (ch2)) |
| - | ch2 = tolower (ch2); |
| - | |
| - | } |
| - | while (ch1 == ch2); |
| + | /* END CODE */ |
| - | string++; |
| - | } |
| - | return (TRUE); |
| - | } |
| - | #endif |
| - | /* END CODE */ |
| @@ -1,12 +1,8 @@ | |
| #include "internal.h" | |
| #include <signal.h> | |
| - | const char reboot_usage[] = "reboot\n" |
| - | "\n\t" |
| - | "\treboot the system.\n"; |
| - | |
| extern int | |
| - | reboot_main(struct FileInfo * i, int argc, char * * argv) |
| + | reboot_main(int argc, char ** argv) |
| { | |
| - | return kill(1, SIGUSR2); |
| + | exit( kill(1, SIGUSR2)); |
| } | |
| @@ -4,137 +4,134 @@ | |
| #include <unistd.h> | |
| #include <signal.h> | |
| - | const char kill_usage[] = "kill [-signal] process-id [process-id ...]\n"; |
| + | const char kill_usage[] = "kill [-signal] process-id [process-id ...]\n"; |
| struct signal_name { | |
| - | const char * name; |
| - | int number; |
| + | const char *name; |
| + | int number; |
| }; | |
| const struct signal_name signames[] = { | |
| - | { "HUP", SIGHUP }, |
| - | { "INT", SIGINT }, |
| - | { "QUIT", SIGQUIT }, |
| - | { "ILL", SIGILL }, |
| - | { "TRAP", SIGTRAP }, |
| - | { "ABRT", SIGABRT }, |
| + | {"HUP", SIGHUP}, |
| + | {"INT", SIGINT}, |
| + | {"QUIT", SIGQUIT}, |
| + | {"ILL", SIGILL}, |
| + | {"TRAP", SIGTRAP}, |
| + | {"ABRT", SIGABRT}, |
| #ifndef __alpha__ | |
| - | { "IOT", SIGIOT }, |
| + | {"IOT", SIGIOT}, |
| #endif | |
| #if defined(sparc) || defined(__alpha__) | |
| - | { "EMT", SIGEMT }, |
| + | {"EMT", SIGEMT}, |
| #else | |
| - | { "BUS", SIGBUS }, |
| + | {"BUS", SIGBUS}, |
| #endif | |
| - | { "FPE", SIGFPE }, |
| - | { "KILL", SIGKILL }, |
| + | {"FPE", SIGFPE}, |
| + | {"KILL", SIGKILL}, |
| #if defined(sparc) || defined(__alpha__) | |
| - | { "BUS", SIGBUS }, |
| + | {"BUS", SIGBUS}, |
| #else | |
| - | { "USR1", SIGUSR1 }, |
| + | {"USR1", SIGUSR1}, |
| #endif | |
| - | { "SEGV", SIGSEGV }, |
| + | {"SEGV", SIGSEGV}, |
| #if defined(sparc) || defined(__alpha__) | |
| - | { "SYS", SIGSYS }, |
| + | {"SYS", SIGSYS}, |
| #else | |
| - | { "USR2", SIGUSR2 }, |
| + | {"USR2", SIGUSR2}, |
| #endif | |
| - | { "PIPE", SIGPIPE }, |
| - | { "ALRM", SIGALRM }, |
| - | { "TERM", SIGTERM }, |
| + | {"PIPE", SIGPIPE}, |
| + | {"ALRM", SIGALRM}, |
| + | {"TERM", SIGTERM}, |
| #if defined(sparc) || defined(__alpha__) | |
| - | { "URG", SIGURG }, |
| - | { "STOP", SIGSTOP }, |
| - | { "TSTP", SIGTSTP }, |
| - | { "CONT", SIGCONT }, |
| - | { "CHLD", SIGCHLD }, |
| - | { "TTIN", SIGTTIN }, |
| - | { "TTOU", SIGTTOU }, |
| - | { "IO", SIGIO }, |
| + | {"URG", SIGURG}, |
| + | {"STOP", SIGSTOP}, |
| + | {"TSTP", SIGTSTP}, |
| + | {"CONT", SIGCONT}, |
| + | {"CHLD", SIGCHLD}, |
| + | {"TTIN", SIGTTIN}, |
| + | {"TTOU", SIGTTOU}, |
| + | {"IO", SIGIO}, |
| # ifndef __alpha__ | |
| - | { "POLL", SIGIO }, |
| + | {"POLL", SIGIO}, |
| # endif | |
| - | { "XCPU", SIGXCPU }, |
| - | { "XFSZ", SIGXFSZ }, |
| - | { "VTALRM", SIGVTALRM }, |
| - | { "PROF", SIGPROF }, |
| - | { "WINCH", SIGWINCH }, |
| + | {"XCPU", SIGXCPU}, |
| + | {"XFSZ", SIGXFSZ}, |
| + | {"VTALRM", SIGVTALRM}, |
| + | {"PROF", SIGPROF}, |
| + | {"WINCH", SIGWINCH}, |
| # ifdef __alpha__ | |
| - | { "INFO", SIGINFO }, |
| + | {"INFO", SIGINFO}, |
| # else | |
| - | { "LOST", SIGLOST }, |
| + | {"LOST", SIGLOST}, |
| # endif | |
| - | { "USR1", SIGUSR1 }, |
| - | { "USR2", SIGUSR2 }, |
| + | {"USR1", SIGUSR1}, |
| + | {"USR2", SIGUSR2}, |
| #else | |
| - | { "STKFLT", SIGSTKFLT }, |
| - | { "CHLD", SIGCHLD }, |
| - | { "CONT", SIGCONT }, |
| - | { "STOP", SIGSTOP }, |
| - | { "TSTP", SIGTSTP }, |
| - | { "TTIN", SIGTTIN }, |
| - | { "TTOU", SIGTTOU }, |
| - | { "URG", SIGURG }, |
| - | { "XCPU", SIGXCPU }, |
| - | { "XFSZ", SIGXFSZ }, |
| - | { "VTALRM", SIGVTALRM }, |
| - | { "PROF", SIGPROF }, |
| - | { "WINCH", SIGWINCH }, |
| - | { "IO", SIGIO }, |
| - | { "POLL", SIGPOLL }, |
| - | { "PWR", SIGPWR }, |
| - | { "UNUSED", SIGUNUSED }, |
| + | {"STKFLT", SIGSTKFLT}, |
| + | {"CHLD", SIGCHLD}, |
| + | {"CONT", SIGCONT}, |
| + | {"STOP", SIGSTOP}, |
| + | {"TSTP", SIGTSTP}, |
| + | {"TTIN", SIGTTIN}, |
| + | {"TTOU", SIGTTOU}, |
| + | {"URG", SIGURG}, |
| + | {"XCPU", SIGXCPU}, |
| + | {"XFSZ", SIGXFSZ}, |
| + | {"VTALRM", SIGVTALRM}, |
| + | {"PROF", SIGPROF}, |
| + | {"WINCH", SIGWINCH}, |
| + | {"IO", SIGIO}, |
| + | {"POLL", SIGPOLL}, |
| + | {"PWR", SIGPWR}, |
| + | {"UNUSED", SIGUNUSED}, |
| #endif | |
| - | { 0, 0 } |
| + | {0, 0} |
| }; | |
| - | extern int |
| - | kill_main(struct FileInfo * i, int argc, char * * argv) |
| + | extern int kill_main (int argc, char **argv) |
| { | |
| - | int had_error = 0; |
| - | int sig = SIGTERM; |
| - | if ( argv[1][0] == '-' ) { |
| - | if ( argv[1][1] >= '0' && argv[1][1] <= '9' ) { |
| - | sig = atoi(&argv[1][1]); |
| - | if ( sig < 0 || sig >= NSIG ) { |
| - | usage(kill_usage); |
| - | exit(-1); |
| - | } |
| - | } |
| - | else { |
| - | const struct signal_name * s = signames; |
| - | for ( ; ; ) { |
| - | if ( strcmp(s->name, &argv[1][1]) == 0 ) { |
| - | sig = s->number; |
| - | break; |
| - | } |
| - | s++; |
| - | if ( s->name == 0 ) { |
| - | usage(kill_usage); |
| - | exit(-1); |
| - | } |
| - | } |
| - | } |
| - | argv++; |
| - | argc--; |
| + | int had_error = 0; |
| + | int sig = SIGTERM; |
| - | } |
| - | while ( argc > 1 ) { |
| - | int pid; |
| - | if ( argv[1][0] < '0' || argv[1][0] > '9' ) { |
| - | usage(kill_usage); |
| - | exit(-1); |
| - | } |
| - | pid = atoi(argv[1]); |
| - | if ( kill(pid, sig) != 0 ) { |
| - | had_error = 1; |
| - | perror(argv[1]); |
| + | |
| + | |
| + | if (argv[1][0] == '-') { |
| + | if (argv[1][1] >= '0' && argv[1][1] <= '9') { |
| + | sig = atoi (&argv[1][1]); |
| + | if (sig < 0 || sig >= NSIG) |
| + | goto end; |
| + | } else { |
| + | const struct signal_name *s = signames; |
| + | for (;;) { |
| + | if (strcmp (s->name, &argv[1][1]) == 0) { |
| + | sig = s->number; |
| + | break; |
| } | |
| - | argv++; |
| - | argc--; |
| + | s++; |
| + | if (s->name == 0) |
| + | goto end; |
| + | } |
| + | } |
| + | argv++; |
| + | argc--; |
| + | |
| + | } |
| + | while (argc > 1) { |
| + | int pid; |
| + | if (argv[1][0] < '0' || argv[1][0] > '9') |
| + | goto end; |
| + | pid = atoi (argv[1]); |
| + | if (kill (pid, sig) != 0) { |
| + | had_error = 1; |
| + | perror (argv[1]); |
| } | |
| - | if ( had_error ) |
| - | return -1; |
| - | else |
| - | return 0; |
| + | argv++; |
| + | argc--; |
| + | } |
| + | if (had_error) { |
| + | end: |
| + | fprintf(stderr, "Usage: %s\n", kill_usage); |
| + | exit ( FALSE); |
| + | } |
| + | exit (TRUE); |
| } | |
| @@ -9,39 +9,44 @@ | |
| * | |
| * made against libc6 | |
| */ | |
| - | |
| + | |
| #include "internal.h" | |
| #include <stdio.h> | |
| #include <utmp.h> | |
| - | const char dutmp_usage[] = "dutmp\n" |
| - | "\n" |
| - | "\tDump file or stdin utmp file format to stdout, pipe delimited.\n" |
| - | "\tdutmp /var/run/utmp\n"; |
| + | const char dutmp_usage[] = "dutmp\n" |
| + | "\n" |
| + | "\tDump file or stdin utmp file format to stdout, pipe delimited.\n" |
| + | "\tdutmp /var/run/utmp\n"; |
| - | extern int |
| - | dutmp_fn(const struct FileInfo * i) |
| + | extern int dutmp_fn (int argc, char **argv) |
| { | |
| - | FILE * f = stdin; |
| - | struct utmp * ut = (struct utmp *) malloc(sizeof(struct utmp) ); |
| - | |
| - | if ( i ) |
| - | if (! (f = fopen(i->source, "r"))) { |
| - | name_and_error(i->source); |
| - | return 1; |
| - | } |
| - | |
| - | while (fread (ut, 1, sizeof(struct utmp), f)) { |
| - | //printf("%d:%d:%s:%s:%s:%s:%d:%d:%ld:%ld:%ld:%x\n", |
| - | printf("%d|%d|%s|%s|%s|%s|%d|%d|%ld|%ld|%ld|%x\n", |
| - | ut->ut_type, ut->ut_pid, ut->ut_line, |
| - | ut->ut_id, ut->ut_user, ut->ut_host, |
| - | ut->ut_exit.e_termination, ut->ut_exit.e_exit, |
| - | ut->ut_session, |
| - | ut->ut_tv.tv_sec, ut->ut_tv.tv_usec, |
| - | ut->ut_addr); |
| - | } |
| - | |
| - | return 0; |
| + | FILE *f = stdin; |
| + | struct utmp ut; |
| + | |
| + | if ((argc < 2) || (**(argv + 1) == '-')) { |
| + | fprintf (stderr, "Usage: %s %s\n", *argv, dutmp_usage); |
| + | exit (FALSE); |
| + | } |
| + | |
| + | if ( **(++argv) == 0 ) { |
| + | f = fopen (*(++argv), "r"); |
| + | if (f < 0 ) { |
| + | perror (*argv); |
| + | exit (FALSE); |
| + | } |
| + | } |
| + | |
| + | while (fread (&ut, 1, sizeof (struct utmp), f)) { |
| + | // printf("%d:%d:%s:%s:%s:%s:%d:%d:%ld:%ld:%ld:%x\n", |
| + | printf ("%d|%d|%s|%s|%s|%s|%d|%d|%ld|%ld|%ld|%x\n", |
| + | ut.ut_type, ut.ut_pid, ut.ut_line, |
| + | ut.ut_id, ut.ut_user, ut.ut_host, |
| + | ut.ut_exit.e_termination, ut.ut_exit.e_exit, |
| + | ut.ut_session, |
| + | ut.ut_tv.tv_sec, ut.ut_tv.tv_usec, ut.ut_addr); |
| + | } |
| + | |
| + | exit (TRUE); |
| } | |
| @@ -19,27 +19,48 @@ | |
| * | |
| */ | |
| + | |
| + | /* Turning this off makes things a bit smaller (and less pretty) */ |
| + | #define BB_MORE_TERM |
| + | |
| + | |
| + | |
| #include "internal.h" | |
| #include <stdio.h> | |
| #include <signal.h> | |
| + | |
| const char more_usage[] = "[file ...]"; | |
| - | //#define ERASE_STUFF |
| + | |
| + | #ifdef BB_MORE_TERM |
| + | #include <termios.h> |
| + | #include <signal.h> |
| + | #include <sys/ioctl.h> |
| + | |
| + | FILE *cin; |
| + | struct termios initial_settings, new_settings; |
| + | |
| + | void gotsig(int sig) { |
| + | tcsetattr(fileno(cin), TCSANOW, &initial_settings); |
| + | exit( TRUE); |
| + | } |
| + | #endif |
| extern int more_main(int argc, char **argv) | |
| { | |
| - | int c, lines=0; |
| + | int c, lines=0, input; |
| int next_page=0, rows = 24; | |
| - | #ifdef ERASE_STUFF |
| - | int cols=79; |
| + | #ifdef BB_MORE_TERM |
| + | int cols; |
| + | struct winsize win; |
| #endif | |
| struct stat st; | |
| FILE *file = stdin; | |
| if ( strcmp(*argv,"--help")==0 || strcmp(*argv,"-h")==0 ) { | |
| fprintf(stderr, "Usage: %s %s", *argv, more_usage); | |
| - | return(FALSE); |
| + | exit(FALSE); |
| } | |
| argc--; | |
| argv++; | |
| @@ -48,23 +69,47 @@ extern int more_main(int argc, char **argv) | |
| file = fopen(*argv, "r"); | |
| if (file == NULL) { | |
| perror("Can't open file"); | |
| - | return(FALSE); |
| + | exit(FALSE); |
| } | |
| fstat(fileno(file), &st); | |
| fprintf(stderr, "hi\n"); | |
| + | #ifdef BB_MORE_TERM |
| + | cin = fopen("/dev/tty", "r"); |
| + | tcgetattr(fileno(cin),&initial_settings); |
| + | new_settings = initial_settings; |
| + | new_settings.c_lflag &= ~ICANON; |
| + | new_settings.c_lflag &= ~ECHO; |
| + | tcsetattr(fileno(cin), TCSANOW, &new_settings); |
| + | |
| + | (void) signal(SIGINT, gotsig); |
| + | |
| + | ioctl(STDOUT_FILENO, TIOCGWINSZ, &win); |
| + | if (win.ws_row > 4) rows = win.ws_row - 2; |
| + | if (win.ws_col > 0) cols = win.ws_col - 1; |
| + | |
| + | |
| + | #endif |
| while ((c = getc(file)) != EOF) { | |
| if ( next_page ) { | |
| int len=0; | |
| next_page = 0; | |
| lines=0; | |
| - | len = fprintf(stdout, "--More-- (%d%% of %ld bytes)", |
| + | len = fprintf(stdout, "--More-- (%d%% of %ld bytes)%s", |
| (int) (100*( (double) ftell(file) / (double) st.st_size )), | |
| - | st.st_size); |
| + | st.st_size, |
| + | #ifdef BB_MORE_TERM |
| + | "" |
| + | #else |
| + | "\n" |
| + | #endif |
| + | ); |
| + | |
| fflush(stdout); | |
| - | getc( stdin); |
| - | #ifdef ERASE_STUFF |
| - | /* Try to erase the "More" message */ |
| + | input = getc( stdin); |
| + | |
| + | #ifdef BB_MORE_TERM |
| + | /* Erase the "More" message */ |
| while(len-- > 0) | |
| putc('\b', stdout); | |
| while(len++ < cols) | |
| @@ -73,7 +118,12 @@ extern int more_main(int argc, char **argv) | |
| putc('\b', stdout); | |
| fflush(stdout); | |
| #endif | |
| + | |
| } | |
| + | if (input=='q') |
| + | goto end; |
| + | if (input==' ' && c == '\n' ) |
| + | next_page = 1; |
| if ( c == '\n' && ++lines == (rows + 1) ) | |
| next_page = 1; | |
| putc(c, stdout); | |
| @@ -84,7 +134,10 @@ extern int more_main(int argc, char **argv) | |
| argc--; | |
| argv++; | |
| } | |
| - | return(TRUE); |
| + | end: |
| + | #ifdef BB_MORE_TERM |
| + | gotsig(0); |
| + | #endif |
| + | exit(TRUE); |
| } | |
| - | |
| @@ -4,137 +4,134 @@ | |
| #include <unistd.h> | |
| #include <signal.h> | |
| - | const char kill_usage[] = "kill [-signal] process-id [process-id ...]\n"; |
| + | const char kill_usage[] = "kill [-signal] process-id [process-id ...]\n"; |
| struct signal_name { | |
| - | const char * name; |
| - | int number; |
| + | const char *name; |
| + | int number; |
| }; | |
| const struct signal_name signames[] = { | |
| - | { "HUP", SIGHUP }, |
| - | { "INT", SIGINT }, |
| - | { "QUIT", SIGQUIT }, |
| - | { "ILL", SIGILL }, |
| - | { "TRAP", SIGTRAP }, |
| - | { "ABRT", SIGABRT }, |
| + | {"HUP", SIGHUP}, |
| + | {"INT", SIGINT}, |
| + | {"QUIT", SIGQUIT}, |
| + | {"ILL", SIGILL}, |
| + | {"TRAP", SIGTRAP}, |
| + | {"ABRT", SIGABRT}, |
| #ifndef __alpha__ | |
| - | { "IOT", SIGIOT }, |
| + | {"IOT", SIGIOT}, |
| #endif | |
| #if defined(sparc) || defined(__alpha__) | |
| - | { "EMT", SIGEMT }, |
| + | {"EMT", SIGEMT}, |
| #else | |
| - | { "BUS", SIGBUS }, |
| + | {"BUS", SIGBUS}, |
| #endif | |
| - | { "FPE", SIGFPE }, |
| - | { "KILL", SIGKILL }, |
| + | {"FPE", SIGFPE}, |
| + | {"KILL", SIGKILL}, |
| #if defined(sparc) || defined(__alpha__) | |
| - | { "BUS", SIGBUS }, |
| + | {"BUS", SIGBUS}, |
| #else | |
| - | { "USR1", SIGUSR1 }, |
| + | {"USR1", SIGUSR1}, |
| #endif | |
| - | { "SEGV", SIGSEGV }, |
| + | {"SEGV", SIGSEGV}, |
| #if defined(sparc) || defined(__alpha__) | |
| - | { "SYS", SIGSYS }, |
| + | {"SYS", SIGSYS}, |
| #else | |
| - | { "USR2", SIGUSR2 }, |
| + | {"USR2", SIGUSR2}, |
| #endif | |
| - | { "PIPE", SIGPIPE }, |
| - | { "ALRM", SIGALRM }, |
| - | { "TERM", SIGTERM }, |
| + | {"PIPE", SIGPIPE}, |
| + | {"ALRM", SIGALRM}, |
| + | {"TERM", SIGTERM}, |
| #if defined(sparc) || defined(__alpha__) | |
| - | { "URG", SIGURG }, |
| - | { "STOP", SIGSTOP }, |
| - | { "TSTP", SIGTSTP }, |
| - | { "CONT", SIGCONT }, |
| - | { "CHLD", SIGCHLD }, |
| - | { "TTIN", SIGTTIN }, |
| - | { "TTOU", SIGTTOU }, |
| - | { "IO", SIGIO }, |
| + | {"URG", SIGURG}, |
| + | {"STOP", SIGSTOP}, |
| + | {"TSTP", SIGTSTP}, |
| + | {"CONT", SIGCONT}, |
| + | {"CHLD", SIGCHLD}, |
| + | {"TTIN", SIGTTIN}, |
| + | {"TTOU", SIGTTOU}, |
| + | {"IO", SIGIO}, |
| # ifndef __alpha__ | |
| - | { "POLL", SIGIO }, |
| + | {"POLL", SIGIO}, |
| # endif | |
| - | { "XCPU", SIGXCPU }, |
| - | { "XFSZ", SIGXFSZ }, |
| - | { "VTALRM", SIGVTALRM }, |
| - | { "PROF", SIGPROF }, |
| - | { "WINCH", SIGWINCH }, |
| + | {"XCPU", SIGXCPU}, |
| + | {"XFSZ", SIGXFSZ}, |
| + | {"VTALRM", SIGVTALRM}, |
| + | {"PROF", SIGPROF}, |
| + | {"WINCH", SIGWINCH}, |
| # ifdef __alpha__ | |
| - | { "INFO", SIGINFO }, |
| + | {"INFO", SIGINFO}, |
| # else | |
| - | { "LOST", SIGLOST }, |
| + | {"LOST", SIGLOST}, |
| # endif | |
| - | { "USR1", SIGUSR1 }, |
| - | { "USR2", SIGUSR2 }, |
| + | {"USR1", SIGUSR1}, |
| + | {"USR2", SIGUSR2}, |
| #else | |
| - | { "STKFLT", SIGSTKFLT }, |
| - | { "CHLD", SIGCHLD }, |
| - | { "CONT", SIGCONT }, |
| - | { "STOP", SIGSTOP }, |
| - | { "TSTP", SIGTSTP }, |
| - | { "TTIN", SIGTTIN }, |
| - | { "TTOU", SIGTTOU }, |
| - | { "URG", SIGURG }, |
| - | { "XCPU", SIGXCPU }, |
| - | { "XFSZ", SIGXFSZ }, |
| - | { "VTALRM", SIGVTALRM }, |
| - | { "PROF", SIGPROF }, |
| - | { "WINCH", SIGWINCH }, |
| - | { "IO", SIGIO }, |
| - | { "POLL", SIGPOLL }, |
| - | { "PWR", SIGPWR }, |
| - | { "UNUSED", SIGUNUSED }, |
| + | {"STKFLT", SIGSTKFLT}, |
| + | {"CHLD", SIGCHLD}, |
| + | {"CONT", SIGCONT}, |
| + | {"STOP", SIGSTOP}, |
| + | {"TSTP", SIGTSTP}, |
| + | {"TTIN", SIGTTIN}, |
| + | {"TTOU", SIGTTOU}, |
| + | {"URG", SIGURG}, |
| + | {"XCPU", SIGXCPU}, |
| + | {"XFSZ", SIGXFSZ}, |
| + | {"VTALRM", SIGVTALRM}, |
| + | {"PROF", SIGPROF}, |
| + | {"WINCH", SIGWINCH}, |
| + | {"IO", SIGIO}, |
| + | {"POLL", SIGPOLL}, |
| + | {"PWR", SIGPWR}, |
| + | {"UNUSED", SIGUNUSED}, |
| #endif | |
| - | { 0, 0 } |
| + | {0, 0} |
| }; | |
| - | extern int |
| - | kill_main(struct FileInfo * i, int argc, char * * argv) |
| + | extern int kill_main (int argc, char **argv) |
| { | |
| - | int had_error = 0; |
| - | int sig = SIGTERM; |
| - | if ( argv[1][0] == '-' ) { |
| - | if ( argv[1][1] >= '0' && argv[1][1] <= '9' ) { |
| - | sig = atoi(&argv[1][1]); |
| - | if ( sig < 0 || sig >= NSIG ) { |
| - | usage(kill_usage); |
| - | exit(-1); |
| - | } |
| - | } |
| - | else { |
| - | const struct signal_name * s = signames; |
| - | for ( ; ; ) { |
| - | if ( strcmp(s->name, &argv[1][1]) == 0 ) { |
| - | sig = s->number; |
| - | break; |
| - | } |
| - | s++; |
| - | if ( s->name == 0 ) { |
| - | usage(kill_usage); |
| - | exit(-1); |
| - | } |
| - | } |
| - | } |
| - | argv++; |
| - | argc--; |
| + | int had_error = 0; |
| + | int sig = SIGTERM; |
| - | } |
| - | while ( argc > 1 ) { |
| - | int pid; |
| - | if ( argv[1][0] < '0' || argv[1][0] > '9' ) { |
| - | usage(kill_usage); |
| - | exit(-1); |
| - | } |
| - | pid = atoi(argv[1]); |
| - | if ( kill(pid, sig) != 0 ) { |
| - | had_error = 1; |
| - | perror(argv[1]); |
| + | |
| + | |
| + | if (argv[1][0] == '-') { |
| + | if (argv[1][1] >= '0' && argv[1][1] <= '9') { |
| + | sig = atoi (&argv[1][1]); |
| + | if (sig < 0 || sig >= NSIG) |
| + | goto end; |
| + | } else { |
| + | const struct signal_name *s = signames; |
| + | for (;;) { |
| + | if (strcmp (s->name, &argv[1][1]) == 0) { |
| + | sig = s->number; |
| + | break; |
| } | |
| - | argv++; |
| - | argc--; |
| + | s++; |
| + | if (s->name == 0) |
| + | goto end; |
| + | } |
| + | } |
| + | argv++; |
| + | argc--; |
| + | |
| + | } |
| + | while (argc > 1) { |
| + | int pid; |
| + | if (argv[1][0] < '0' || argv[1][0] > '9') |
| + | goto end; |
| + | pid = atoi (argv[1]); |
| + | if (kill (pid, sig) != 0) { |
| + | had_error = 1; |
| + | perror (argv[1]); |
| } | |
| - | if ( had_error ) |
| - | return -1; |
| - | else |
| - | return 0; |
| + | argv++; |
| + | argc--; |
| + | } |
| + | if (had_error) { |
| + | end: |
| + | fprintf(stderr, "Usage: %s\n", kill_usage); |
| + | exit ( FALSE); |
| + | } |
| + | exit (TRUE); |
| } | |
| @@ -1,12 +1,13 @@ | |
| #include "internal.h" | |
| #include <stdio.h> | |
| + | #include <dirent.h> |
| const char pwd_usage[] = "Print the current directory.\n"; | |
| extern int | |
| pwd_main(int argc, char * * argv) | |
| { | |
| - | char buf[1024]; |
| + | char buf[NAME_MAX]; |
| if ( getcwd(buf, sizeof(buf)) == NULL ) { | |
| perror("get working directory"); | |
| @@ -1,12 +1,8 @@ | |
| #include "internal.h" | |
| #include <signal.h> | |
| - | const char reboot_usage[] = "reboot\n" |
| - | "\n\t" |
| - | "\treboot the system.\n"; |
| - | |
| extern int | |
| - | reboot_main(struct FileInfo * i, int argc, char * * argv) |
| + | reboot_main(int argc, char ** argv) |
| { | |
| - | return kill(1, SIGUSR2); |
| + | exit( kill(1, SIGUSR2)); |
| } | |
| @@ -1,15 +1,20 @@ | |
| #include "internal.h" | |
| #include <stdio.h> | |
| - | const char sleep_usage[] = "sleep seconds\n" |
| - | "\n" |
| - | "\tPause program execution for the given number of seconds.\n"; |
| + | const char sleep_usage[] = " NUMBER\n" |
| + | "Pause for NUMBER seconds.\n"; |
| extern int | |
| - | sleep_main(struct FileInfo * i, int argc, char * * argv) |
| + | sleep_main(int argc, char * * argv) |
| { | |
| - | if ( sleep(atoi(argv[1])) != 0 ) |
| - | return -1; |
| - | else |
| - | return 0; |
| + | if ( (argc < 2) || (**(argv+1) == '-') ) { |
| + | fprintf(stderr, "Usage: %s %s", *argv, sleep_usage); |
| + | exit(FALSE); |
| + | } |
| + | |
| + | if ( sleep(atoi(*(++argv))) != 0 ) { |
| + | perror( "sleep"); |
| + | exit (FALSE); |
| + | } else |
| + | exit (TRUE); |
| } | |
| @@ -7,7 +7,7 @@ | |
| * This allows creation, extraction, and listing of tar files. | |
| * | |
| * Permission to distribute this code under the GPL has been granted. | |
| - | * Modified for busybox by Erik Andersen <[email protected]> <[email protected]> |
| + | * Modified for busybox by Erik Andersen <[email protected]> |
| */ | |
| @@ -15,11 +15,11 @@ | |
| #ifdef BB_TAR | |
| - | const char tar_usage[] = |
| - | "Create, extract, or list files from a TAR file\n\n" |
| - | "usage: tar -[cxtvOf] [tarFileName] [FILE] ...\n" |
| - | "\tc=create, x=extract, t=list contents, v=verbose,\n" |
| - | "\tO=extract to stdout, f=tarfile or \"-\" for stdin\n"; |
| + | const char tar_usage[] = |
| + | "Create, extract, or list files from a TAR file\n\n" |
| + | "usage: tar -[cxtvOf] [tarFileName] [FILE] ...\n" |
| + | "\tc=create, x=extract, t=list contents, v=verbose,\n" |
| + | "\tO=extract to stdout, f=tarfile or \"-\" for stdin\n"; |
| @@ -42,24 +42,23 @@ const char tar_usage[] = | |
| * This structure is always embedded in a TAR_BLOCK_SIZE sized block | |
| * with zero padding. We only process this information minimally. | |
| */ | |
| - | typedef struct |
| - | { |
| - | char name[TAR_NAME_SIZE]; |
| - | char mode[8]; |
| - | char uid[8]; |
| - | char gid[8]; |
| - | char size[12]; |
| - | char mtime[12]; |
| - | char checkSum[8]; |
| - | char typeFlag; |
| - | char linkName[TAR_NAME_SIZE]; |
| - | char magic[6]; |
| - | char version[2]; |
| - | char uname[32]; |
| - | char gname[32]; |
| - | char devMajor[8]; |
| - | char devMinor[8]; |
| - | char prefix[155]; |
| + | typedef struct { |
| + | char name[TAR_NAME_SIZE]; |
| + | char mode[8]; |
| + | char uid[8]; |
| + | char gid[8]; |
| + | char size[12]; |
| + | char mtime[12]; |
| + | char checkSum[8]; |
| + | char typeFlag; |
| + | char linkName[TAR_NAME_SIZE]; |
| + | char magic[6]; |
| + | char version[2]; |
| + | char uname[32]; |
| + | char gname[32]; |
| + | char devMajor[8]; |
| + | char devMinor[8]; |
| + | char prefix[155]; |
| } TarHeader; | |
| #define TAR_MAGIC "ustar" | |
| @@ -73,168 +72,162 @@ typedef struct | |
| /* | |
| * Static data. | |
| */ | |
| - | 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]; |
| + | 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]; |
| /* | |
| * Static data associated with the tar file. | |
| */ | |
| - | static const char * tarName; |
| - | static int tarFd; |
| - | static dev_t tarDev; |
| - | static ino_t tarInode; |
| + | static const char *tarName; |
| + | static int tarFd; |
| + | static dev_t tarDev; |
| + | static ino_t tarInode; |
| /* | |
| * Local procedures to restore files from a tar file. | |
| */ | |
| - | 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 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, |
| - | int fileCount, char ** fileTable); |
| + | static void readHeader (const TarHeader * hp, |
| + | int fileCount, char **fileTable); |
| /* | |
| * Local procedures to save files into a tar file. | |
| */ | |
| - | static void saveFile(const char * fileName, int seeLinks); |
| + | static void saveFile (const char *fileName, int seeLinks); |
| - | static void saveRegularFile(const char * fileName, |
| - | const struct stat * statbuf); |
| + | static void saveRegularFile (const char *fileName, |
| + | const struct stat *statbuf); |
| - | static void saveDirectory(const char * fileName, |
| - | const struct stat * statbuf); |
| + | static void saveDirectory (const char *fileName, |
| + | const struct stat *statbuf); |
| - | static int wantFileName(const char * fileName, |
| - | int fileCount, char ** fileTable); |
| + | static int wantFileName (const char *fileName, |
| + | int fileCount, char **fileTable); |
| - | static void writeHeader(const char * fileName, |
| - | const struct stat * statbuf); |
| + | static void writeHeader (const char *fileName, const struct stat *statbuf); |
| - | static void writeTarFile(int fileCount, char ** fileTable); |
| - | static void writeTarBlock(const char * buf, int len); |
| - | static int putOctal(char * cp, int len, long value); |
| + | static void writeTarFile (int fileCount, char **fileTable); |
| + | static void writeTarBlock (const char *buf, int len); |
| + | static int putOctal (char *cp, int len, long value); |
| - | extern int |
| - | tar_main(int argc, char ** argv) |
| + | extern int tar_main (int argc, char **argv) |
| { | |
| - | const char * options; |
| - | |
| - | argc--; |
| - | argv++; |
| - | |
| - | if (argc < 1) |
| - | { |
| - | fprintf(stderr, "%s", tar_usage); |
| - | return 1; |
| - | } |
| - | |
| - | |
| - | errorFlag = FALSE; |
| - | extractFlag = FALSE; |
| - | createFlag = FALSE; |
| - | listFlag = FALSE; |
| - | verboseFlag = FALSE; |
| - | tostdoutFlag = FALSE; |
| - | tarName = NULL; |
| - | tarDev = 0; |
| - | tarInode = 0; |
| - | tarFd = -1; |
| - | |
| - | /* |
| - | * Parse the options. |
| - | */ |
| - | options = *argv++; |
| - | argc--; |
| - | |
| - | if (**argv == '-') { |
| - | for (; *options; options++) |
| - | { |
| - | switch (*options) |
| - | { |
| - | case 'f': |
| - | if (tarName != NULL) |
| - | { |
| - | fprintf(stderr, "Only one 'f' option allowed\n"); |
| - | |
| - | return 1; |
| - | } |
| - | |
| - | tarName = *argv++; |
| - | argc--; |
| - | |
| - | break; |
| + | const char *options; |
| + | |
| + | argc--; |
| + | argv++; |
| + | |
| + | if (argc < 1) { |
| + | fprintf (stderr, "%s", tar_usage); |
| + | exit (FALSE); |
| + | } |
| + | |
| + | |
| + | errorFlag = FALSE; |
| + | extractFlag = FALSE; |
| + | createFlag = FALSE; |
| + | listFlag = FALSE; |
| + | verboseFlag = FALSE; |
| + | tostdoutFlag = FALSE; |
| + | tarName = NULL; |
| + | tarDev = 0; |
| + | tarInode = 0; |
| + | tarFd = -1; |
| + | |
| + | /* |
| + | * Parse the options. |
| + | */ |
| + | options = *argv++; |
| + | argc--; |
| + | |
| + | if (**argv == '-') { |
| + | for (; *options; options++) { |
| + | switch (*options) { |
| + | case 'f': |
| + | if (tarName != NULL) { |
| + | fprintf (stderr, "Only one 'f' option allowed\n"); |
| + | |
| + | exit (FALSE); |
| + | } |
| - | case 't': |
| - | listFlag = TRUE; |
| - | break; |
| + | tarName = *argv++; |
| + | argc--; |
| - | case 'x': |
| - | extractFlag = TRUE; |
| - | break; |
| + | break; |
| - | case 'c': |
| - | createFlag = TRUE; |
| - | break; |
| + | case 't': |
| + | listFlag = TRUE; |
| + | break; |
| - | case 'v': |
| - | verboseFlag = TRUE; |
| - | break; |
| + | case 'x': |
| + | extractFlag = TRUE; |
| + | break; |
| - | case 'O': |
| - | tostdoutFlag = TRUE; |
| - | break; |
| + | case 'c': |
| + | createFlag = TRUE; |
| + | break; |
| - | case '-': |
| - | break; |
| + | case 'v': |
| + | verboseFlag = TRUE; |
| + | break; |
| - | default: |
| - | fprintf(stderr, "Unknown tar flag '%c'\n", *options); |
| + | case 'O': |
| + | tostdoutFlag = TRUE; |
| + | break; |
| - | return 1; |
| - | } |
| - | } |
| - | } |
| + | case '-': |
| + | break; |
| - | /* |
| - | * Validate the options. |
| - | */ |
| - | if (extractFlag + listFlag + createFlag != 1) |
| - | { |
| - | fprintf(stderr, "Exactly one of 'c', 'x' or 't' must be specified\n"); |
| + | default: |
| + | fprintf (stderr, "Unknown tar flag '%c'\n", *options); |
| - | return 1; |
| + | exit (FALSE); |
| + | } |
| } | |
| - | |
| - | /* |
| - | * Do the correct type of action supplying the rest of the |
| - | * command line arguments as the list of files to process. |
| - | */ |
| - | if (createFlag) |
| - | writeTarFile(argc, argv); |
| - | else |
| - | readTarFile(argc, argv); |
| - | if (errorFlag) |
| - | fprintf(stderr, "\n"); |
| - | return( errorFlag); |
| + | } |
| + | |
| + | /* |
| + | * Validate the options. |
| + | */ |
| + | if (extractFlag + listFlag + createFlag != 1) { |
| + | fprintf (stderr, |
| + | "Exactly one of 'c', 'x' or 't' must be specified\n"); |
| + | |
| + | exit (FALSE); |
| + | } |
| + | |
| + | /* |
| + | * Do the correct type of action supplying the rest of the |
| + | * command line arguments as the list of files to process. |
| + | */ |
| + | if (createFlag) |
| + | writeTarFile (argc, argv); |
| + | else |
| + | readTarFile (argc, argv); |
| + | if (errorFlag) |
| + | fprintf (stderr, "\n"); |
| + | exit (errorFlag); |
| } | |
| @@ -242,128 +235,119 @@ tar_main(int argc, char ** argv) | |
| * Read a tar file and extract or list the specified files within it. | |
| * If the list is empty than all files are extracted or listed. | |
| */ | |
| - | static void |
| - | readTarFile(int fileCount, char ** fileTable) |
| + | static void readTarFile (int fileCount, char **fileTable) |
| { | |
| - | const char * cp; |
| - | int cc; |
| - | int inCc; |
| - | int blockSize; |
| - | char buf[BUF_SIZE]; |
| - | |
| - | skipFileFlag = FALSE; |
| - | badHeader = FALSE; |
| - | warnedRoot = FALSE; |
| - | eofFlag = FALSE; |
| - | inHeader = TRUE; |
| - | inCc = 0; |
| - | dataCc = 0; |
| - | outFd = -1; |
| - | blockSize = sizeof(buf); |
| - | cp = buf; |
| - | |
| - | /* |
| - | * Open the tar file for reading. |
| + | const char *cp; |
| + | int cc; |
| + | int inCc; |
| + | int blockSize; |
| + | char buf[BUF_SIZE]; |
| + | |
| + | skipFileFlag = FALSE; |
| + | badHeader = FALSE; |
| + | warnedRoot = FALSE; |
| + | eofFlag = FALSE; |
| + | inHeader = TRUE; |
| + | inCc = 0; |
| + | dataCc = 0; |
| + | outFd = -1; |
| + | blockSize = sizeof (buf); |
| + | cp = buf; |
| + | |
| + | /* |
| + | * Open the tar file for reading. |
| + | */ |
| + | if ((tarName == NULL) || !strcmp (tarName, "-")) { |
| + | tarFd = STDIN; |
| + | } else |
| + | tarFd = open (tarName, O_RDONLY); |
| + | |
| + | if (tarFd < 0) { |
| + | perror (tarName); |
| + | errorFlag = TRUE; |
| + | return; |
| + | } |
| + | |
| + | /* |
| + | * Read blocks from the file until an end of file header block |
| + | * has been seen. (A real end of file from a read is an error.) |
| + | */ |
| + | while (!eofFlag) { |
| + | /* |
| + | * Read the next block of data if necessary. |
| + | * This will be a large block if possible, which we will |
| + | * then process in the small tar blocks. |
| */ | |
| - | if ( (tarName==NULL) || !strcmp( tarName, "-") ) { |
| - | tarFd = STDIN; |
| - | } |
| - | else |
| - | tarFd = open(tarName, O_RDONLY); |
| + | if (inCc <= 0) { |
| + | cp = buf; |
| + | inCc = fullRead (tarFd, buf, blockSize); |
| - | if (tarFd < 0) |
| - | { |
| - | perror(tarName); |
| + | if (inCc < 0) { |
| + | perror (tarName); |
| errorFlag = TRUE; | |
| - | return; |
| + | goto done; |
| + | } |
| + | |
| + | if (inCc == 0) { |
| + | fprintf (stderr, |
| + | "Unexpected end of file from \"%s\"", tarName); |
| + | errorFlag = TRUE; |
| + | goto done; |
| + | } |
| } | |
| - | /* |
| - | * Read blocks from the file until an end of file header block |
| - | * has been seen. (A real end of file from a read is an error.) |
| + | /* |
| + | * If we are expecting a header block then examine it. |
| */ | |
| - | while (!eofFlag) |
| - | { |
| - | /* |
| - | * Read the next block of data if necessary. |
| - | * This will be a large block if possible, which we will |
| - | * then process in the small tar blocks. |
| - | */ |
| - | if (inCc <= 0) |
| - | { |
| - | cp = buf; |
| - | inCc = fullRead(tarFd, buf, blockSize); |
| - | |
| - | if (inCc < 0) |
| - | { |
| - | perror(tarName); |
| - | errorFlag=TRUE; |
| - | goto done; |
| - | } |
| - | |
| - | if (inCc == 0) |
| - | { |
| - | fprintf(stderr, |
| - | "Unexpected end of file from \"%s\"", |
| - | tarName); |
| - | errorFlag=TRUE; |
| - | goto done; |
| - | } |
| - | } |
| + | if (inHeader) { |
| + | readHeader ((const TarHeader *) cp, fileCount, fileTable); |
| - | /* |
| - | * If we are expecting a header block then examine it. |
| - | */ |
| - | if (inHeader) |
| - | { |
| - | readHeader((const TarHeader *) cp, fileCount, fileTable); |
| + | cp += TAR_BLOCK_SIZE; |
| + | inCc -= TAR_BLOCK_SIZE; |
| - | cp += TAR_BLOCK_SIZE; |
| - | inCc -= TAR_BLOCK_SIZE; |
| - | |
| - | continue; |
| - | } |
| - | |
| - | /* |
| - | * We are currently handling the data for a file. |
| - | * Process the minimum of the amount of data we have available |
| - | * and the amount left to be processed for the file. |
| - | */ |
| - | cc = inCc; |
| - | |
| - | if (cc > dataCc) |
| - | cc = dataCc; |
| - | |
| - | readData(cp, cc); |
| - | |
| - | /* |
| - | * If the amount left isn't an exact multiple of the tar block |
| - | * size then round it up to the next block boundary since there |
| - | * is padding at the end of the file. |
| - | */ |
| - | if (cc % TAR_BLOCK_SIZE) |
| - | cc += TAR_BLOCK_SIZE - (cc % TAR_BLOCK_SIZE); |
| - | |
| - | cp += cc; |
| - | inCc -= cc; |
| + | continue; |
| } | |
| - | done: |
| - | /* |
| - | * Close the tar file if needed. |
| + | /* |
| + | * We are currently handling the data for a file. |
| + | * Process the minimum of the amount of data we have available |
| + | * and the amount left to be processed for the file. |
| */ | |
| - | if ((tarFd >= 0) && (close(tarFd) < 0)) |
| - | perror(tarName); |
| + | cc = inCc; |
| + | |
| + | if (cc > dataCc) |
| + | cc = dataCc; |
| - | /* |
| - | * Close the output file if needed. |
| - | * This is only done here on a previous error and so no |
| - | * message is required on errors. |
| + | readData (cp, cc); |
| + | |
| + | /* |
| + | * If the amount left isn't an exact multiple of the tar block |
| + | * size then round it up to the next block boundary since there |
| + | * is padding at the end of the file. |
| */ | |
| - | if (tostdoutFlag==FALSE) { |
| - | if (outFd >= 0) |
| - | (void) close(outFd); |
| - | } |
| + | if (cc % TAR_BLOCK_SIZE) |
| + | cc += TAR_BLOCK_SIZE - (cc % TAR_BLOCK_SIZE); |
| + | |
| + | cp += cc; |
| + | inCc -= cc; |
| + | } |
| + | |
| + | done: |
| + | /* |
| + | * Close the tar file if needed. |
| + | */ |
| + | if ((tarFd >= 0) && (close (tarFd) < 0)) |
| + | perror (tarName); |
| + | |
| + | /* |
| + | * Close the output file if needed. |
| + | * This is only done here on a previous error and so no |
| + | * message is required on errors. |
| + | */ |
| + | if (tostdoutFlag == FALSE) { |
| + | if (outFd >= 0) |
| + | (void) close (outFd); |
| + | } |
| } | |
| @@ -373,332 +357,307 @@ done: | |
| * the end of the tar file. | |
| */ | |
| static void | |
| - | readHeader(const TarHeader * hp, int fileCount, char ** fileTable) |
| + | readHeader (const TarHeader * hp, int fileCount, char **fileTable) |
| { | |
| - | int mode; |
| - | int uid; |
| - | int gid; |
| - | int checkSum; |
| - | long size; |
| - | time_t mtime; |
| - | const char * name; |
| - | int cc; |
| - | int hardLink; |
| - | int softLink; |
| - | |
| - | /* |
| - | * If the block is completely empty, then this is the end of the |
| - | * archive file. If the name is null, then just skip this header. |
| - | */ |
| - | name = hp->name; |
| - | |
| - | if (*name == '\0') |
| - | { |
| - | for (cc = TAR_BLOCK_SIZE; cc > 0; cc--) |
| - | { |
| - | if (*name++) |
| - | return; |
| - | } |
| - | |
| - | eofFlag = TRUE; |
| - | |
| + | int mode; |
| + | int uid; |
| + | int gid; |
| + | int checkSum; |
| + | long size; |
| + | time_t mtime; |
| + | const char *name; |
| + | int cc; |
| + | int hardLink; |
| + | int softLink; |
| + | |
| + | /* |
| + | * If the block is completely empty, then this is the end of the |
| + | * archive file. If the name is null, then just skip this header. |
| + | */ |
| + | name = hp->name; |
| + | |
| + | if (*name == '\0') { |
| + | for (cc = TAR_BLOCK_SIZE; cc > 0; cc--) { |
| + | if (*name++) |
| return; | |
| } | |
| - | /* |
| - | * There is another file in the archive to examine. |
| - | * Extract the encoded information and check it. |
| - | */ |
| - | mode = getOctal(hp->mode, sizeof(hp->mode)); |
| - | uid = getOctal(hp->uid, sizeof(hp->uid)); |
| - | gid = getOctal(hp->gid, sizeof(hp->gid)); |
| - | size = getOctal(hp->size, sizeof(hp->size)); |
| - | mtime = getOctal(hp->mtime, sizeof(hp->mtime)); |
| - | checkSum = getOctal(hp->checkSum, sizeof(hp->checkSum)); |
| + | eofFlag = TRUE; |
| - | if ((mode < 0) || (uid < 0) || (gid < 0) || (size < 0)) |
| - | { |
| - | if (!badHeader) |
| - | fprintf(stderr, "Bad tar header, skipping\n"); |
| + | return; |
| + | } |
| - | badHeader = TRUE; |
| + | /* |
| + | * There is another file in the archive to examine. |
| + | * Extract the encoded information and check it. |
| + | */ |
| + | mode = getOctal (hp->mode, sizeof (hp->mode)); |
| + | uid = getOctal (hp->uid, sizeof (hp->uid)); |
| + | gid = getOctal (hp->gid, sizeof (hp->gid)); |
| + | size = getOctal (hp->size, sizeof (hp->size)); |
| + | mtime = getOctal (hp->mtime, sizeof (hp->mtime)); |
| + | checkSum = getOctal (hp->checkSum, sizeof (hp->checkSum)); |
| - | return; |
| - | } |
| + | if ((mode < 0) || (uid < 0) || (gid < 0) || (size < 0)) { |
| + | if (!badHeader) |
| + | fprintf (stderr, "Bad tar header, skipping\n"); |
| - | badHeader = FALSE; |
| - | skipFileFlag = FALSE; |
| + | badHeader = TRUE; |
| - | /* |
| - | * Check for the file modes. |
| - | */ |
| - | hardLink = ((hp->typeFlag == TAR_TYPE_HARD_LINK) || |
| + | return; |
| + | } |
| + | |
| + | badHeader = FALSE; |
| + | skipFileFlag = FALSE; |
| + | |
| + | /* |
| + | * Check for the file modes. |
| + | */ |
| + | hardLink = ((hp->typeFlag == TAR_TYPE_HARD_LINK) || |
| (hp->typeFlag == TAR_TYPE_HARD_LINK - '0')); | |
| - | softLink = ((hp->typeFlag == TAR_TYPE_SOFT_LINK) || |
| + | softLink = ((hp->typeFlag == TAR_TYPE_SOFT_LINK) || |
| (hp->typeFlag == TAR_TYPE_SOFT_LINK - '0')); | |
| - | /* |
| - | * Check for a directory or a regular file. |
| - | */ |
| - | if (name[strlen(name) - 1] == '/') |
| - | mode |= S_IFDIR; |
| - | else if ((mode & S_IFMT) == 0) |
| - | mode |= S_IFREG; |
| - | |
| - | /* |
| - | * Check for absolute paths in the file. |
| - | * If we find any, then warn the user and make them relative. |
| - | */ |
| - | if (*name == '/') |
| - | { |
| - | while (*name == '/') |
| - | name++; |
| - | |
| - | if (!warnedRoot) |
| - | { |
| - | fprintf(stderr, |
| - | "Absolute path detected, removing leading slashes\n"); |
| - | } |
| - | |
| - | warnedRoot = TRUE; |
| + | /* |
| + | * Check for a directory or a regular file. |
| + | */ |
| + | if (name[strlen (name) - 1] == '/') |
| + | mode |= S_IFDIR; |
| + | else if ((mode & S_IFMT) == 0) |
| + | mode |= S_IFREG; |
| + | |
| + | /* |
| + | * Check for absolute paths in the file. |
| + | * If we find any, then warn the user and make them relative. |
| + | */ |
| + | if (*name == '/') { |
| + | while (*name == '/') |
| + | name++; |
| + | |
| + | if (!warnedRoot) { |
| + | fprintf (stderr, |
| + | "Absolute path detected, removing leading slashes\n"); |
| } | |
| - | /* |
| - | * See if we want this file to be restored. |
| - | * If not, then set up to skip it. |
| - | */ |
| - | if (!wantFileName(name, fileCount, fileTable)) |
| - | { |
| - | if (!hardLink && !softLink && S_ISREG(mode)) |
| - | { |
| - | inHeader = (size == 0); |
| - | dataCc = size; |
| - | } |
| - | |
| - | skipFileFlag = TRUE; |
| - | |
| - | return; |
| + | warnedRoot = TRUE; |
| + | } |
| + | |
| + | /* |
| + | * See if we want this file to be restored. |
| + | * If not, then set up to skip it. |
| + | */ |
| + | if (!wantFileName (name, fileCount, fileTable)) { |
| + | if (!hardLink && !softLink && S_ISREG (mode)) { |
| + | inHeader = (size == 0); |
| + | dataCc = size; |
| } | |
| - | /* |
| - | * This file is to be handled. |
| - | * If we aren't extracting then just list information about the file. |
| - | */ |
| - | if (!extractFlag) |
| - | { |
| - | if (verboseFlag) |
| - | { |
| - | printf("%s %3d/%-d %9ld %s %s", modeString(mode), |
| - | uid, gid, size, timeString(mtime), name); |
| - | } |
| - | else |
| - | printf("%s", name); |
| - | |
| - | if (hardLink) |
| - | printf(" (link to \"%s\")", hp->linkName); |
| - | else if (softLink) |
| - | printf(" (symlink to \"%s\")", hp->linkName); |
| - | else if (S_ISREG(mode)) |
| - | { |
| - | inHeader = (size == 0); |
| - | dataCc = size; |
| - | } |
| - | |
| - | printf("\n"); |
| + | skipFileFlag = TRUE; |
| - | return; |
| - | } |
| + | return; |
| + | } |
| - | /* |
| - | * We really want to extract the file. |
| - | */ |
| - | if (verboseFlag) |
| - | printf("x %s\n", name); |
| + | /* |
| + | * This file is to be handled. |
| + | * If we aren't extracting then just list information about the file. |
| + | */ |
| + | if (!extractFlag) { |
| + | if (verboseFlag) { |
| + | printf ("%s %3d/%-d %9ld %s %s", modeString (mode), |
| + | uid, gid, size, timeString (mtime), name); |
| + | } else |
| + | printf ("%s", name); |
| if (hardLink) | |
| - | { |
| - | if (link(hp->linkName, name) < 0) |
| - | perror(name); |
| - | |
| - | return; |
| - | } |
| - | |
| - | if (softLink) |
| - | { |
| - | #ifdef S_ISLNK |
| - | if (symlink(hp->linkName, name) < 0) |
| - | perror(name); |
| - | #else |
| - | fprintf(stderr, "Cannot create symbolic links\n"); |
| - | #endif |
| - | return; |
| + | printf (" (link to \"%s\")", hp->linkName); |
| + | else if (softLink) |
| + | printf (" (symlink to \"%s\")", hp->linkName); |
| + | else if (S_ISREG (mode)) { |
| + | inHeader = (size == 0); |
| + | dataCc = size; |
| } | |
| - | /* |
| - | * If the file is a directory, then just create the path. |
| - | */ |
| - | if (S_ISDIR(mode)) |
| - | { |
| - | createPath(name, mode); |
| + | printf ("\n"); |
| - | return; |
| - | } |
| + | return; |
| + | } |
| - | /* |
| - | * There is a file to write. |
| - | * First create the path to it if necessary with a default permission. |
| - | */ |
| - | createPath(name, 0777); |
| + | /* |
| + | * We really want to extract the file. |
| + | */ |
| + | if (verboseFlag) |
| + | printf ("x %s\n", name); |
| - | inHeader = (size == 0); |
| - | dataCc = size; |
| + | if (hardLink) { |
| + | if (link (hp->linkName, name) < 0) |
| + | perror (name); |
| - | /* |
| - | * Start the output file. |
| - | */ |
| - | if (tostdoutFlag==TRUE) |
| - | outFd = STDOUT; |
| - | else |
| - | outFd = open(name, O_WRONLY | O_CREAT | O_TRUNC, mode); |
| - | |
| - | if (outFd < 0) |
| - | { |
| - | perror(name); |
| - | skipFileFlag = TRUE; |
| - | return; |
| - | } |
| + | return; |
| + | } |
| - | /* |
| - | * If the file is empty, then that's all we need to do. |
| - | */ |
| - | if (size == 0 && tostdoutFlag == FALSE) |
| - | { |
| - | (void) close(outFd); |
| - | outFd = -1; |
| - | } |
| + | if (softLink) { |
| + | #ifdef S_ISLNK |
| + | if (symlink (hp->linkName, name) < 0) |
| + | perror (name); |
| + | #else |
| + | fprintf (stderr, "Cannot create symbolic links\n"); |
| + | #endif |
| + | return; |
| + | } |
| + | |
| + | /* |
| + | * If the file is a directory, then just create the path. |
| + | */ |
| + | if (S_ISDIR (mode)) { |
| + | createPath (name, mode); |
| + | |
| + | return; |
| + | } |
| + | |
| + | /* |
| + | * There is a file to write. |
| + | * First create the path to it if necessary with a default permission. |
| + | */ |
| + | createPath (name, 0777); |
| + | |
| + | inHeader = (size == 0); |
| + | dataCc = size; |
| + | |
| + | /* |
| + | * Start the output file. |
| + | */ |
| + | if (tostdoutFlag == TRUE) |
| + | outFd = STDOUT; |
| + | else |
| + | outFd = open (name, O_WRONLY | O_CREAT | O_TRUNC, mode); |
| + | |
| + | if (outFd < 0) { |
| + | perror (name); |
| + | skipFileFlag = TRUE; |
| + | return; |
| + | } |
| + | |
| + | /* |
| + | * If the file is empty, then that's all we need to do. |
| + | */ |
| + | if (size == 0 && tostdoutFlag == FALSE) { |
| + | (void) close (outFd); |
| + | outFd = -1; |
| + | } |
| } | |
| /* | |
| * Handle a data block of some specified size that was read. | |
| */ | |
| - | static void |
| - | readData(const char * cp, int count) |
| + | static void readData (const char *cp, int count) |
| { | |
| - | /* |
| - | * Reduce the amount of data left in this file. |
| - | * If there is no more data left, then we need to read |
| - | * the header again. |
| - | */ |
| - | dataCc -= count; |
| - | |
| - | if (dataCc <= 0) |
| - | inHeader = TRUE; |
| - | |
| - | /* |
| - | * If we aren't extracting files or this file is being |
| - | * skipped then do nothing more. |
| - | */ |
| - | if (!extractFlag || skipFileFlag) |
| - | return; |
| + | /* |
| + | * Reduce the amount of data left in this file. |
| + | * If there is no more data left, then we need to read |
| + | * the header again. |
| + | */ |
| + | dataCc -= count; |
| + | |
| + | if (dataCc <= 0) |
| + | inHeader = TRUE; |
| - | /* |
| - | * Write the data to the output file. |
| - | */ |
| - | if (fullWrite(outFd, cp, count) < 0) |
| - | { |
| - | perror(outName); |
| - | if (tostdoutFlag==FALSE) { |
| - | (void) close(outFd); |
| - | outFd = -1; |
| - | } |
| - | skipFileFlag = TRUE; |
| - | return; |
| + | /* |
| + | * If we aren't extracting files or this file is being |
| + | * skipped then do nothing more. |
| + | */ |
| + | if (!extractFlag || skipFileFlag) |
| + | return; |
| + | |
| + | /* |
| + | * Write the data to the output file. |
| + | */ |
| + | if (fullWrite (outFd, cp, count) < 0) { |
| + | perror (outName); |
| + | if (tostdoutFlag == FALSE) { |
| + | (void) close (outFd); |
| + | outFd = -1; |
| } | |
| + | skipFileFlag = TRUE; |
| + | return; |
| + | } |
| + | |
| + | /* |
| + | * If the write failed, close the file and disable further |
| + | * writes to this file. |
| + | */ |
| + | if (dataCc <= 0 && tostdoutFlag == FALSE) { |
| + | if (close (outFd)) |
| + | perror (outName); |
| - | /* |
| - | * If the write failed, close the file and disable further |
| - | * writes to this file. |
| - | */ |
| - | if (dataCc <= 0 && tostdoutFlag==FALSE) |
| - | { |
| - | if (close(outFd)) |
| - | perror(outName); |
| - | |
| - | outFd = -1; |
| - | } |
| + | outFd = -1; |
| + | } |
| } | |
| /* | |
| * Write a tar file containing the specified files. | |
| */ | |
| - | static void |
| - | writeTarFile(int fileCount, char ** fileTable) |
| + | static void writeTarFile (int fileCount, char **fileTable) |
| { | |
| - | struct stat statbuf; |
| - | |
| - | /* |
| - | * Make sure there is at least one file specified. |
| - | */ |
| - | if (fileCount <= 0) |
| - | { |
| - | fprintf(stderr, "No files specified to be saved\n"); |
| - | errorFlag=TRUE; |
| - | } |
| - | |
| - | /* |
| - | * Create the tar file for writing. |
| - | */ |
| - | if ( (tarName==NULL) || !strcmp( tarName, "-") ) { |
| - | tostdoutFlag = TRUE; |
| - | tarFd = STDOUT; |
| - | } |
| - | else |
| - | tarFd = open(tarName, O_WRONLY | O_CREAT | O_TRUNC, 0666); |
| - | |
| - | if (tarFd < 0) |
| - | { |
| - | perror(tarName); |
| - | errorFlag=TRUE; |
| - | return; |
| - | } |
| - | |
| - | /* |
| - | * Get the device and inode of the tar file for checking later. |
| - | */ |
| - | if (fstat(tarFd, &statbuf) < 0) |
| - | { |
| - | perror(tarName); |
| - | errorFlag = TRUE; |
| - | goto done; |
| - | } |
| - | |
| - | tarDev = statbuf.st_dev; |
| - | tarInode = statbuf.st_ino; |
| - | |
| - | /* |
| - | * Append each file name into the archive file. |
| - | * Follow symbolic links for these top level file names. |
| - | */ |
| - | while (!errorFlag && (fileCount-- > 0)) |
| - | { |
| - | saveFile(*fileTable++, FALSE); |
| - | } |
| - | |
| - | /* |
| - | * Now write an empty block of zeroes to end the archive. |
| - | */ |
| - | writeTarBlock("", 1); |
| - | |
| - | |
| - | done: |
| - | /* |
| - | * Close the tar file and check for errors if it was opened. |
| - | */ |
| - | if ( (tostdoutFlag==FALSE) && (tarFd >= 0) && (close(tarFd) < 0)) |
| - | perror(tarName); |
| + | struct stat statbuf; |
| + | |
| + | /* |
| + | * Make sure there is at least one file specified. |
| + | */ |
| + | if (fileCount <= 0) { |
| + | fprintf (stderr, "No files specified to be saved\n"); |
| + | errorFlag = TRUE; |
| + | } |
| + | |
| + | /* |
| + | * Create the tar file for writing. |
| + | */ |
| + | if ((tarName == NULL) || !strcmp (tarName, "-")) { |
| + | tostdoutFlag = TRUE; |
| + | tarFd = STDOUT; |
| + | } else |
| + | tarFd = open (tarName, O_WRONLY | O_CREAT | O_TRUNC, 0666); |
| + | |
| + | if (tarFd < 0) { |
| + | perror (tarName); |
| + | errorFlag = TRUE; |
| + | return; |
| + | } |
| + | |
| + | /* |
| + | * Get the device and inode of the tar file for checking later. |
| + | */ |
| + | if (fstat (tarFd, &statbuf) < 0) { |
| + | perror (tarName); |
| + | errorFlag = TRUE; |
| + | goto done; |
| + | } |
| + | |
| + | tarDev = statbuf.st_dev; |
| + | tarInode = statbuf.st_ino; |
| + | |
| + | /* |
| + | * Append each file name into the archive file. |
| + | * Follow symbolic links for these top level file names. |
| + | */ |
| + | while (!errorFlag && (fileCount-- > 0)) { |
| + | saveFile (*fileTable++, FALSE); |
| + | } |
| + | |
| + | /* |
| + | * Now write an empty block of zeroes to end the archive. |
| + | */ |
| + | writeTarBlock ("", 1); |
| + | |
| + | |
| + | done: |
| + | /* |
| + | * Close the tar file and check for errors if it was opened. |
| + | */ |
| + | if ((tostdoutFlag == FALSE) && (tarFd >= 0) && (close (tarFd) < 0)) |
| + | perror (tarName); |
| } | |
| @@ -709,76 +668,70 @@ done: | |
| * flag indicates whether or not we want to see symbolic links as | |
| * they really are, instead of blindly following them. | |
| */ | |
| - | static void |
| - | saveFile(const char * fileName, int seeLinks) |
| + | static void saveFile (const char *fileName, int seeLinks) |
| { | |
| - | int status; |
| - | int mode; |
| - | struct stat statbuf; |
| + | int status; |
| + | int mode; |
| + | struct stat statbuf; |
| - | if (verboseFlag) |
| - | printf("a %s\n", fileName); |
| + | if (verboseFlag) |
| + | printf ("a %s\n", fileName); |
| - | /* |
| - | * Check that the file name will fit in the header. |
| - | */ |
| - | if (strlen(fileName) >= TAR_NAME_SIZE) |
| - | { |
| - | fprintf(stderr, "%s: File name is too long\n", fileName); |
| + | /* |
| + | * Check that the file name will fit in the header. |
| + | */ |
| + | if (strlen (fileName) >= TAR_NAME_SIZE) { |
| + | fprintf (stderr, "%s: File name is too long\n", fileName); |
| - | return; |
| - | } |
| + | return; |
| + | } |
| - | /* |
| - | * Find out about the file. |
| - | */ |
| + | /* |
| + | * Find out about the file. |
| + | */ |
| #ifdef S_ISLNK | |
| - | if (seeLinks) |
| - | status = lstat(fileName, &statbuf); |
| - | else |
| + | if (seeLinks) |
| + | status = lstat (fileName, &statbuf); |
| + | else |
| #endif | |
| - | status = stat(fileName, &statbuf); |
| + | status = stat (fileName, &statbuf); |
| - | if (status < 0) |
| - | { |
| - | perror(fileName); |
| + | if (status < 0) { |
| + | perror (fileName); |
| - | return; |
| - | } |
| + | return; |
| + | } |
| - | /* |
| - | * Make sure we aren't trying to save our file into itself. |
| - | */ |
| - | if ((statbuf.st_dev == tarDev) && (statbuf.st_ino == tarInode)) |
| - | { |
| - | fprintf(stderr, "Skipping saving of archive file itself\n"); |
| + | /* |
| + | * Make sure we aren't trying to save our file into itself. |
| + | */ |
| + | if ((statbuf.st_dev == tarDev) && (statbuf.st_ino == tarInode)) { |
| + | fprintf (stderr, "Skipping saving of archive file itself\n"); |
| - | return; |
| - | } |
| + | return; |
| + | } |
| - | /* |
| - | * Check the type of file. |
| - | */ |
| - | mode = statbuf.st_mode; |
| + | /* |
| + | * Check the type of file. |
| + | */ |
| + | mode = statbuf.st_mode; |
| - | if (S_ISDIR(mode)) |
| - | { |
| - | saveDirectory(fileName, &statbuf); |
| + | if (S_ISDIR (mode)) { |
| + | saveDirectory (fileName, &statbuf); |
| - | return; |
| - | } |
| + | return; |
| + | } |
| - | if (S_ISREG(mode)) |
| - | { |
| - | saveRegularFile(fileName, &statbuf); |
| + | if (S_ISREG (mode)) { |
| + | saveRegularFile (fileName, &statbuf); |
| - | return; |
| - | } |
| + | return; |
| + | } |
| - | /* |
| - | * The file is a strange type of file, ignore it. |
| - | */ |
| - | fprintf(stderr, "%s: not a directory or regular file\n", fileName); |
| + | /* |
| + | * The file is a strange type of file, ignore it. |
| + | */ |
| + | fprintf (stderr, "%s: not a directory or regular file\n", fileName); |
| } | |
| @@ -786,183 +739,173 @@ saveFile(const char * fileName, int seeLinks) | |
| * Save a regular file to the tar file. | |
| */ | |
| static void | |
| - | saveRegularFile(const char * fileName, const struct stat * statbuf) |
| + | saveRegularFile (const char *fileName, const struct stat *statbuf) |
| { | |
| - | int sawEof; |
| - | int fileFd; |
| - | int cc; |
| - | int dataCount; |
| - | long fullDataCount; |
| - | char data[TAR_BLOCK_SIZE * 16]; |
| - | |
| - | /* |
| - | * Open the file for reading. |
| + | int sawEof; |
| + | int fileFd; |
| + | int cc; |
| + | int dataCount; |
| + | long fullDataCount; |
| + | char data[TAR_BLOCK_SIZE * 16]; |
| + | |
| + | /* |
| + | * Open the file for reading. |
| + | */ |
| + | fileFd = open (fileName, O_RDONLY); |
| + | |
| + | if (fileFd < 0) { |
| + | perror (fileName); |
| + | |
| + | return; |
| + | } |
| + | |
| + | /* |
| + | * Write out the header for the file. |
| + | */ |
| + | writeHeader (fileName, statbuf); |
| + | |
| + | /* |
| + | * Write the data blocks of the file. |
| + | * We must be careful to write the amount of data that the stat |
| + | * buffer indicated, even if the file has changed size. Otherwise |
| + | * the tar file will be incorrect. |
| + | */ |
| + | fullDataCount = statbuf->st_size; |
| + | sawEof = FALSE; |
| + | |
| + | while (fullDataCount > 0) { |
| + | /* |
| + | * Get the amount to write this iteration which is |
| + | * the minumum of the amount left to write and the |
| + | * buffer size. |
| */ | |
| - | fileFd = open(fileName, O_RDONLY); |
| - | |
| - | if (fileFd < 0) |
| - | { |
| - | perror(fileName); |
| + | dataCount = sizeof (data); |
| - | return; |
| - | } |
| + | if (dataCount > fullDataCount) |
| + | dataCount = (int) fullDataCount; |
| - | /* |
| - | * Write out the header for the file. |
| + | /* |
| + | * Read the data from the file if we haven't seen the |
| + | * end of file yet. |
| */ | |
| - | writeHeader(fileName, statbuf); |
| + | cc = 0; |
| - | /* |
| - | * Write the data blocks of the file. |
| - | * We must be careful to write the amount of data that the stat |
| - | * buffer indicated, even if the file has changed size. Otherwise |
| - | * the tar file will be incorrect. |
| - | */ |
| - | fullDataCount = statbuf->st_size; |
| - | sawEof = FALSE; |
| - | |
| - | while (fullDataCount > 0) |
| - | { |
| - | /* |
| - | * Get the amount to write this iteration which is |
| - | * the minumum of the amount left to write and the |
| - | * buffer size. |
| - | */ |
| - | dataCount = sizeof(data); |
| - | |
| - | if (dataCount > fullDataCount) |
| - | dataCount = (int) fullDataCount; |
| - | |
| - | /* |
| - | * Read the data from the file if we haven't seen the |
| - | * end of file yet. |
| - | */ |
| - | cc = 0; |
| - | |
| - | if (!sawEof) |
| - | { |
| - | cc = fullRead(fileFd, data, dataCount); |
| - | |
| - | if (cc < 0) |
| - | { |
| - | perror(fileName); |
| - | |
| - | (void) close(fileFd); |
| - | errorFlag = TRUE; |
| - | |
| - | return; |
| - | } |
| - | |
| - | /* |
| - | * If the file ended too soon, complain and set |
| - | * a flag so we will zero fill the rest of it. |
| - | */ |
| - | if (cc < dataCount) |
| - | { |
| - | fprintf(stderr, |
| - | "%s: Short read - zero filling", |
| - | fileName); |
| - | |
| - | sawEof = TRUE; |
| - | } |
| - | } |
| + | if (!sawEof) { |
| + | cc = fullRead (fileFd, data, dataCount); |
| - | /* |
| - | * Zero fill the rest of the data if necessary. |
| - | */ |
| - | if (cc < dataCount) |
| - | memset(data + cc, 0, dataCount - cc); |
| + | if (cc < 0) { |
| + | perror (fileName); |
| - | /* |
| - | * Write the buffer to the TAR file. |
| - | */ |
| - | writeTarBlock(data, dataCount); |
| + | (void) close (fileFd); |
| + | errorFlag = TRUE; |
| - | fullDataCount -= dataCount; |
| + | return; |
| + | } |
| + | |
| + | /* |
| + | * If the file ended too soon, complain and set |
| + | * a flag so we will zero fill the rest of it. |
| + | */ |
| + | if (cc < dataCount) { |
| + | fprintf (stderr, |
| + | "%s: Short read - zero filling", fileName); |
| + | |
| + | sawEof = TRUE; |
| + | } |
| } | |
| - | /* |
| - | * Close the file. |
| + | /* |
| + | * Zero fill the rest of the data if necessary. |
| + | */ |
| + | if (cc < dataCount) |
| + | memset (data + cc, 0, dataCount - cc); |
| + | |
| + | /* |
| + | * Write the buffer to the TAR file. |
| */ | |
| - | if ( (tostdoutFlag==FALSE) && close(fileFd) < 0) |
| - | fprintf(stderr, "%s: close: %s\n", fileName, strerror(errno)); |
| + | writeTarBlock (data, dataCount); |
| + | |
| + | fullDataCount -= dataCount; |
| + | } |
| + | |
| + | /* |
| + | * Close the file. |
| + | */ |
| + | if ((tostdoutFlag == FALSE) && close (fileFd) < 0) |
| + | fprintf (stderr, "%s: close: %s\n", fileName, strerror (errno)); |
| } | |
| /* | |
| * Save a directory and all of its files to the tar file. | |
| */ | |
| - | static void |
| - | saveDirectory(const char * dirName, const struct stat * statbuf) |
| + | static void saveDirectory (const char *dirName, const struct stat *statbuf) |
| { | |
| - | DIR * dir; |
| - | struct dirent * entry; |
| - | int needSlash; |
| - | char fullName[PATH_LEN]; |
| - | |
| - | /* |
| - | * Construct the directory name as used in the tar file by appending |
| - | * a slash character to it. |
| - | */ |
| - | strcpy(fullName, dirName); |
| - | strcat(fullName, "/"); |
| - | |
| - | /* |
| - | * Write out the header for the directory entry. |
| - | */ |
| - | writeHeader(fullName, statbuf); |
| - | |
| - | /* |
| - | * Open the directory. |
| - | */ |
| - | dir = opendir(dirName); |
| - | |
| - | if (dir == NULL) |
| - | { |
| - | fprintf(stderr, "Cannot read directory \"%s\": %s\n", |
| - | dirName, strerror(errno)); |
| - | |
| - | return; |
| + | DIR *dir; |
| + | struct dirent *entry; |
| + | int needSlash; |
| + | char fullName[PATH_LEN]; |
| + | |
| + | /* |
| + | * Construct the directory name as used in the tar file by appending |
| + | * a slash character to it. |
| + | */ |
| + | strcpy (fullName, dirName); |
| + | strcat (fullName, "/"); |
| + | |
| + | /* |
| + | * Write out the header for the directory entry. |
| + | */ |
| + | writeHeader (fullName, statbuf); |
| + | |
| + | /* |
| + | * Open the directory. |
| + | */ |
| + | dir = opendir (dirName); |
| + | |
| + | if (dir == NULL) { |
| + | fprintf (stderr, "Cannot read directory \"%s\": %s\n", |
| + | dirName, strerror (errno)); |
| + | |
| + | return; |
| + | } |
| + | |
| + | /* |
| + | * See if a slash is needed. |
| + | */ |
| + | needSlash = (*dirName && (dirName[strlen (dirName) - 1] != '/')); |
| + | |
| + | /* |
| + | * Read all of the directory entries and check them, |
| + | * except for the current and parent directory entries. |
| + | */ |
| + | while (!errorFlag && ((entry = readdir (dir)) != NULL)) { |
| + | if ((strcmp (entry->d_name, ".") == 0) || |
| + | (strcmp (entry->d_name, "..") == 0)) { |
| + | continue; |
| } | |
| - | /* |
| - | * See if a slash is needed. |
| + | /* |
| + | * Build the full path name to the file. |
| */ | |
| - | needSlash = (*dirName && (dirName[strlen(dirName) - 1] != '/')); |
| + | strcpy (fullName, dirName); |
| - | /* |
| - | * Read all of the directory entries and check them, |
| - | * except for the current and parent directory entries. |
| - | */ |
| - | while (!errorFlag && ((entry = readdir(dir)) != NULL)) |
| - | { |
| - | if ((strcmp(entry->d_name, ".") == 0) || |
| - | (strcmp(entry->d_name, "..") == 0)) |
| - | { |
| - | continue; |
| - | } |
| - | |
| - | /* |
| - | * Build the full path name to the file. |
| - | */ |
| - | strcpy(fullName, dirName); |
| + | if (needSlash) |
| + | strcat (fullName, "/"); |
| - | if (needSlash) |
| - | strcat(fullName, "/"); |
| + | strcat (fullName, entry->d_name); |
| - | strcat(fullName, entry->d_name); |
| - | |
| - | /* |
| - | * Write this file to the tar file, noticing whether or not |
| - | * the file is a symbolic link. |
| - | */ |
| - | saveFile(fullName, TRUE); |
| - | } |
| - | |
| - | /* |
| - | * All done, close the directory. |
| + | /* |
| + | * Write this file to the tar file, noticing whether or not |
| + | * the file is a symbolic link. |
| */ | |
| - | closedir(dir); |
| + | saveFile (fullName, TRUE); |
| + | } |
| + | |
| + | /* |
| + | * All done, close the directory. |
| + | */ |
| + | closedir (dir); |
| } | |
| @@ -970,55 +913,54 @@ saveDirectory(const char * dirName, const struct stat * statbuf) | |
| * Write a tar header for the specified file name and status. | |
| * It is assumed that the file name fits. | |
| */ | |
| - | static void |
| - | writeHeader(const char * fileName, const struct stat * statbuf) |
| + | static void writeHeader (const char *fileName, const struct stat *statbuf) |
| { | |
| - | long checkSum; |
| - | const unsigned char * cp; |
| - | int len; |
| - | TarHeader header; |
| - | |
| - | /* |
| - | * Zero the header block in preparation for filling it in. |
| - | */ |
| - | memset((char *) &header, 0, sizeof(header)); |
| - | |
| - | /* |
| - | * Fill in the header. |
| - | */ |
| - | strcpy(header.name, fileName); |
| - | |
| - | strncpy(header.magic, TAR_MAGIC, sizeof(header.magic)); |
| - | strncpy(header.version, TAR_VERSION, sizeof(header.version)); |
| - | |
| - | putOctal(header.mode, sizeof(header.mode), statbuf->st_mode & 0777); |
| - | putOctal(header.uid, sizeof(header.uid), statbuf->st_uid); |
| - | putOctal(header.gid, sizeof(header.gid), statbuf->st_gid); |
| - | putOctal(header.size, sizeof(header.size), statbuf->st_size); |
| - | putOctal(header.mtime, sizeof(header.mtime), statbuf->st_mtime); |
| - | |
| - | header.typeFlag = TAR_TYPE_REGULAR; |
| - | |
| - | /* |
| - | * Calculate and store the checksum. |
| - | * This is the sum of all of the bytes of the header, |
| - | * with the checksum field itself treated as blanks. |
| - | */ |
| - | memset(header.checkSum, ' ', sizeof(header.checkSum)); |
| - | |
| - | cp = (const unsigned char *) &header; |
| - | len = sizeof(header); |
| - | checkSum = 0; |
| - | |
| - | while (len-- > 0) |
| - | checkSum += *cp++; |
| - | |
| - | putOctal(header.checkSum, sizeof(header.checkSum), checkSum); |
| - | |
| - | /* |
| - | * Write the tar header. |
| - | */ |
| - | writeTarBlock((const char *) &header, sizeof(header)); |
| + | long checkSum; |
| + | const unsigned char *cp; |
| + | int len; |
| + | TarHeader header; |
| + | |
| + | /* |
| + | * Zero the header block in preparation for filling it in. |
| + | */ |
| + | memset ((char *) &header, 0, sizeof (header)); |
| + | |
| + | /* |
| + | * Fill in the header. |
| + | */ |
| + | strcpy (header.name, fileName); |
| + | |
| + | strncpy (header.magic, TAR_MAGIC, sizeof (header.magic)); |
| + | strncpy (header.version, TAR_VERSION, sizeof (header.version)); |
| + | |
| + | putOctal (header.mode, sizeof (header.mode), statbuf->st_mode & 0777); |
| + | putOctal (header.uid, sizeof (header.uid), statbuf->st_uid); |
| + | putOctal (header.gid, sizeof (header.gid), statbuf->st_gid); |
| + | putOctal (header.size, sizeof (header.size), statbuf->st_size); |
| + | putOctal (header.mtime, sizeof (header.mtime), statbuf->st_mtime); |
| + | |
| + | header.typeFlag = TAR_TYPE_REGULAR; |
| + | |
| + | /* |
| + | * Calculate and store the checksum. |
| + | * This is the sum of all of the bytes of the header, |
| + | * with the checksum field itself treated as blanks. |
| + | */ |
| + | memset (header.checkSum, ' ', sizeof (header.checkSum)); |
| + | |
| + | cp = (const unsigned char *) &header; |
| + | len = sizeof (header); |
| + | checkSum = 0; |
| + | |
| + | while (len-- > 0) |
| + | checkSum += *cp++; |
| + | |
| + | putOctal (header.checkSum, sizeof (header.checkSum), checkSum); |
| + | |
| + | /* |
| + | * Write the tar header. |
| + | */ |
| + | writeTarBlock ((const char *) &header, sizeof (header)); |
| } | |
| @@ -1027,59 +969,56 @@ writeHeader(const char * fileName, const struct stat * statbuf) | |
| * The data is always padded out to a multiple of TAR_BLOCK_SIZE. | |
| * The errorFlag static variable is set on an error. | |
| */ | |
| - | static void |
| - | writeTarBlock(const char * buf, int len) |
| + | static void writeTarBlock (const char *buf, int len) |
| { | |
| - | int partialLength; |
| - | int completeLength; |
| - | char fullBlock[TAR_BLOCK_SIZE]; |
| - | |
| - | /* |
| - | * If we had a write error before, then do nothing more. |
| - | */ |
| - | if (errorFlag) |
| - | return; |
| - | |
| - | /* |
| - | * Get the amount of complete and partial blocks. |
| - | */ |
| - | partialLength = len % TAR_BLOCK_SIZE; |
| - | completeLength = len - partialLength; |
| - | |
| - | /* |
| - | * Write all of the complete blocks. |
| - | */ |
| - | if ((completeLength > 0) && !fullWrite(tarFd, buf, completeLength)) |
| - | { |
| - | perror(tarName); |
| - | |
| - | errorFlag = TRUE; |
| - | |
| - | return; |
| - | } |
| - | |
| - | /* |
| - | * If there are no partial blocks left, we are done. |
| - | */ |
| - | if (partialLength == 0) |
| - | return; |
| - | |
| - | /* |
| - | * Copy the partial data into a complete block, and pad the rest |
| - | * of it with zeroes. |
| - | */ |
| - | memcpy(fullBlock, buf + completeLength, partialLength); |
| - | memset(fullBlock + partialLength, 0, TAR_BLOCK_SIZE - partialLength); |
| - | |
| - | /* |
| - | * Write the last complete block. |
| - | */ |
| - | if (!fullWrite(tarFd, fullBlock, TAR_BLOCK_SIZE)) |
| - | { |
| - | perror(tarName); |
| - | |
| - | errorFlag = TRUE; |
| - | } |
| + | int partialLength; |
| + | int completeLength; |
| + | char fullBlock[TAR_BLOCK_SIZE]; |
| + | |
| + | /* |
| + | * If we had a write error before, then do nothing more. |
| + | */ |
| + | if (errorFlag) |
| + | return; |
| + | |
| + | /* |
| + | * Get the amount of complete and partial blocks. |
| + | */ |
| + | partialLength = len % TAR_BLOCK_SIZE; |
| + | completeLength = len - partialLength; |
| + | |
| + | /* |
| + | * Write all of the complete blocks. |
| + | */ |
| + | if ((completeLength > 0) && !fullWrite (tarFd, buf, completeLength)) { |
| + | perror (tarName); |
| + | |
| + | errorFlag = TRUE; |
| + | |
| + | return; |
| + | } |
| + | |
| + | /* |
| + | * If there are no partial blocks left, we are done. |
| + | */ |
| + | if (partialLength == 0) |
| + | return; |
| + | |
| + | /* |
| + | * Copy the partial data into a complete block, and pad the rest |
| + | * of it with zeroes. |
| + | */ |
| + | memcpy (fullBlock, buf + completeLength, partialLength); |
| + | memset (fullBlock + partialLength, 0, TAR_BLOCK_SIZE - partialLength); |
| + | |
| + | /* |
| + | * Write the last complete block. |
| + | */ |
| + | if (!fullWrite (tarFd, fullBlock, TAR_BLOCK_SIZE)) { |
| + | perror (tarName); |
| + | |
| + | errorFlag = TRUE; |
| + | } |
| } | |
| @@ -1089,29 +1028,27 @@ writeTarBlock(const char * buf, int len) | |
| * 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) |
| + | static void createPath (const char *name, int mode) |
| { | |
| - | char * cp; |
| - | char * cpOld; |
| - | char buf[TAR_NAME_SIZE]; |
| + | char *cp; |
| + | char *cpOld; |
| + | char buf[TAR_NAME_SIZE]; |
| - | strcpy(buf, name); |
| + | strcpy (buf, name); |
| - | cp = strchr(buf, '/'); |
| + | cp = strchr (buf, '/'); |
| - | while (cp) |
| - | { |
| - | cpOld = cp; |
| - | cp = strchr(cp + 1, '/'); |
| + | while (cp) { |
| + | cpOld = cp; |
| + | cp = strchr (cp + 1, '/'); |
| - | *cpOld = '\0'; |
| + | *cpOld = '\0'; |
| - | if (mkdir(buf, cp ? 0777 : mode) == 0) |
| - | printf("Directory \"%s\" created\n", buf); |
| + | if (mkdir (buf, cp ? 0777 : mode) == 0) |
| + | printf ("Directory \"%s\" created\n", buf); |
| - | *cpOld = '/'; |
| - | } |
| + | *cpOld = '/'; |
| + | } |
| } | |
| @@ -1120,38 +1057,34 @@ createPath(const char * name, int mode) | |
| * spaces on both sides of the number and with an optional null character | |
| * at the end. Returns -1 on an illegal format. | |
| */ | |
| - | static long |
| - | getOctal(const char * cp, int len) |
| + | static long getOctal (const char *cp, int len) |
| { | |
| - | long val; |
| + | long val; |
| - | while ((len > 0) && (*cp == ' ')) |
| - | { |
| - | cp++; |
| - | len--; |
| - | } |
| + | while ((len > 0) && (*cp == ' ')) { |
| + | cp++; |
| + | len--; |
| + | } |
| - | if ((len == 0) || !isOctal(*cp)) |
| - | return -1; |
| + | if ((len == 0) || !isOctal (*cp)) |
| + | return -1; |
| - | val = 0; |
| + | val = 0; |
| - | while ((len > 0) && isOctal(*cp)) |
| - | { |
| - | val = val * 8 + *cp++ - '0'; |
| - | len--; |
| - | } |
| + | while ((len > 0) && isOctal (*cp)) { |
| + | val = val * 8 + *cp++ - '0'; |
| + | len--; |
| + | } |
| - | while ((len > 0) && (*cp == ' ')) |
| - | { |
| - | cp++; |
| - | len--; |
| - | } |
| + | while ((len > 0) && (*cp == ' ')) { |
| + | cp++; |
| + | len--; |
| + | } |
| - | if ((len > 0) && *cp) |
| - | return -1; |
| + | if ((len > 0) && *cp) |
| + | return -1; |
| - | return val; |
| + | return val; |
| } | |
| @@ -1160,50 +1093,48 @@ getOctal(const char * cp, int len) | |
| * The number is zero and space padded and possibly null padded. | |
| * Returns TRUE if successful. | |
| */ | |
| - | static int |
| - | putOctal(char * cp, int len, long value) |
| + | static int putOctal (char *cp, int len, long value) |
| { | |
| - | int tempLength; |
| - | char * tempString; |
| - | char tempBuffer[32]; |
| - | |
| - | /* |
| - | * Create a string of the specified length with an initial space, |
| - | * leading zeroes and the octal number, and a trailing null. |
| - | */ |
| - | tempString = tempBuffer; |
| - | |
| - | sprintf(tempString, " %0*lo", len - 2, value); |
| - | |
| - | tempLength = strlen(tempString) + 1; |
| - | |
| - | /* |
| - | * If the string is too large, suppress the leading space. |
| - | */ |
| - | if (tempLength > len) |
| - | { |
| - | tempLength--; |
| - | tempString++; |
| - | } |
| - | |
| - | /* |
| - | * If the string is still too large, suppress the trailing null. |
| - | */ |
| - | if (tempLength > len) |
| - | tempLength--; |
| + | int tempLength; |
| + | char *tempString; |
| + | char tempBuffer[32]; |
| + | |
| + | /* |
| + | * Create a string of the specified length with an initial space, |
| + | * leading zeroes and the octal number, and a trailing null. |
| + | */ |
| + | tempString = tempBuffer; |
| + | |
| + | sprintf (tempString, " %0*lo", len - 2, value); |
| + | |
| + | tempLength = strlen (tempString) + 1; |
| + | |
| + | /* |
| + | * If the string is too large, suppress the leading space. |
| + | */ |
| + | if (tempLength > len) { |
| + | tempLength--; |
| + | tempString++; |
| + | } |
| + | |
| + | /* |
| + | * If the string is still too large, suppress the trailing null. |
| + | */ |
| + | if (tempLength > len) |
| + | tempLength--; |
| + | |
| + | /* |
| + | * If the string is still too large, fail. |
| + | */ |
| + | if (tempLength > len) |
| + | return FALSE; |
| - | /* |
| - | * If the string is still too large, fail. |
| - | */ |
| - | if (tempLength > len) |
| - | return FALSE; |
| + | /* |
| + | * Copy the string to the field. |
| + | */ |
| + | memcpy (cp, tempString, len); |
| - | /* |
| - | * Copy the string to the field. |
| - | */ |
| - | memcpy(cp, tempString, len); |
| - | |
| - | return TRUE; |
| + | return TRUE; |
| } | |
| @@ -1213,48 +1144,43 @@ putOctal(char * cp, int len, long value) | |
| * Returns TRUE if the file is selected. | |
| */ | |
| static int | |
| - | wantFileName(const char * fileName, int fileCount, char ** fileTable) |
| + | wantFileName (const char *fileName, int fileCount, char **fileTable) |
| { | |
| - | const char * pathName; |
| - | int fileLength; |
| - | int pathLength; |
| - | |
| - | /* |
| - | * If there are no files in the list, then the file is wanted. |
| - | */ |
| - | if (fileCount == 0) |
| - | return TRUE; |
| + | const char *pathName; |
| + | int fileLength; |
| + | int pathLength; |
| + | |
| + | /* |
| + | * If there are no files in the list, then the file is wanted. |
| + | */ |
| + | if (fileCount == 0) |
| + | return TRUE; |
| - | fileLength = strlen(fileName); |
| + | fileLength = strlen (fileName); |
| - | /* |
| - | * Check each of the test paths. |
| - | */ |
| - | while (fileCount-- > 0) |
| - | { |
| - | pathName = *fileTable++; |
| + | /* |
| + | * Check each of the test paths. |
| + | */ |
| + | while (fileCount-- > 0) { |
| + | pathName = *fileTable++; |
| - | pathLength = strlen(pathName); |
| + | pathLength = strlen (pathName); |
| - | if (fileLength < pathLength) |
| - | continue; |
| + | if (fileLength < pathLength) |
| + | continue; |
| - | if (memcmp(fileName, pathName, pathLength) != 0) |
| - | continue; |
| + | if (memcmp (fileName, pathName, pathLength) != 0) |
| + | continue; |
| - | if ((fileLength == pathLength) || |
| - | (fileName[pathLength] == '/')) |
| - | { |
| - | return TRUE; |
| - | } |
| + | if ((fileLength == pathLength) || (fileName[pathLength] == '/')) { |
| + | return TRUE; |
| } | |
| + | } |
| - | return FALSE; |
| + | return FALSE; |
| } | |
| #endif | |
| /* END CODE */ | |
| - | |
| - | |
| @@ -14,7 +14,6 @@ | |
| #include <linux/unistd.h> | |
| #include <stdio.h> | |
| - | #include <getopt.h> |
| #define __NR_klog __NR_syslog | |
| @@ -22,74 +21,78 @@ | |
| #include <sys/klog.h> | |
| #define klog klogctl | |
| #else | |
| - | static inline _syscall3(int,klog,int,type,char *,b,int,len) |
| - | #endif /* __GLIBC__ */ |
| + | static inline _syscall3 (int, klog, int, type, char *, b, int, len) |
| + | #endif /* __GLIBC__ */ |
| - | const char dmesg_usage[] = "dmesg"; |
| - | int |
| - | dmesg_main(int argc, char * * argv) |
| + | |
| + | static const char dmesg_usage[] = "dmesg [-c] [-n level]\n"; |
| + | |
| + | int dmesg_main (int argc, char **argv) |
| { | |
| - | char buf[4096]; |
| - | int i; |
| - | int n; |
| - | int c; |
| - | int level = 0; |
| - | int lastc; |
| - | int cmd = 3; |
| + | char buf[4096]; |
| + | int i; |
| + | int n; |
| + | int level = 0; |
| + | int lastc; |
| + | int cmd = 3; |
| - | while ((c = getopt( argc, argv, "cn:" )) != EOF) { |
| - | switch (c) { |
| - | case 'c': |
| - | cmd = 4; |
| - | break; |
| - | case 'n': |
| - | cmd = 8; |
| - | level = atoi(optarg); |
| - | break; |
| - | case '?': |
| - | default: |
| - | fprintf(stderr, "%s\n", dmesg_usage); |
| - | exit(1); |
| - | } |
| - | } |
| - | argc -= optind; |
| - | argv += optind; |
| - | |
| - | if (argc > 1) { |
| - | fprintf(stderr, "%s\n", dmesg_usage); |
| - | exit(1); |
| - | } |
| + | argc--; |
| + | argv++; |
| - | if (cmd == 8) { |
| - | n = klog( cmd, NULL, level ); |
| - | if (n < 0) { |
| - | perror( "klog" ); |
| - | exit( 1 ); |
| - | } |
| - | exit( 0 ); |
| - | } |
| + | /* Parse any options */ |
| + | while (argc && **argv == '-') { |
| + | while (*++(*argv)) |
| + | switch (**argv) { |
| + | case 'c': |
| + | cmd = 4; |
| + | break; |
| + | case 'n': |
| + | cmd = 8; |
| + | if (--argc == 0) |
| + | goto end; |
| + | level = atoi (*(++argv)); |
| + | --argc; |
| + | ++argv; |
| + | break; |
| + | default: |
| + | goto end; |
| + | } |
| + | } |
| - | n = klog( cmd, buf, sizeof( buf ) ); |
| - | if (n < 0) { |
| - | perror( "klog" ); |
| - | exit( 1 ); |
| - | } |
| + | if (cmd == 8) { |
| + | n = klog (cmd, NULL, level); |
| + | if (n < 0) { |
| + | perror ("klog"); |
| + | exit (FALSE); |
| + | } |
| + | exit (TRUE); |
| + | } |
| - | lastc = '\n'; |
| - | for (i = 0; i < n; i++) { |
| - | if ((i == 0 || buf[i - 1] == '\n') && buf[i] == '<') { |
| - | i++; |
| - | while (buf[i] >= '0' && buf[i] <= '9') |
| - | i++; |
| - | if (buf[i] == '>') |
| + | n = klog (cmd, buf, sizeof (buf)); |
| + | if (n < 0) { |
| + | perror ("klog"); |
| + | exit (FALSE); |
| + | } |
| + | |
| + | lastc = '\n'; |
| + | for (i = 0; i < n; i++) { |
| + | if ((i == 0 || buf[i - 1] == '\n') && buf[i] == '<') { |
| i++; | |
| - | } |
| - | lastc = buf[i]; |
| - | putchar( lastc ); |
| - | } |
| - | if (lastc != '\n') |
| - | putchar( '\n' ); |
| - | return 0; |
| + | while (buf[i] >= '0' && buf[i] <= '9') |
| + | i++; |
| + | if (buf[i] == '>') |
| + | i++; |
| + | } |
| + | lastc = buf[i]; |
| + | putchar (lastc); |
| + | } |
| + | if (lastc != '\n') |
| + | putchar ('\n'); |
| + | exit (TRUE); |
| + | |
| + | end: |
| + | fprintf (stderr, "Usage: %s\n", dmesg_usage); |
| + | exit (FALSE); |
| } | |
| @@ -19,27 +19,48 @@ | |
| * | |
| */ | |
| + | |
| + | /* Turning this off makes things a bit smaller (and less pretty) */ |
| + | #define BB_MORE_TERM |
| + | |
| + | |
| + | |
| #include "internal.h" | |
| #include <stdio.h> | |
| #include <signal.h> | |
| + | |
| const char more_usage[] = "[file ...]"; | |
| - | //#define ERASE_STUFF |
| + | |
| + | #ifdef BB_MORE_TERM |
| + | #include <termios.h> |
| + | #include <signal.h> |
| + | #include <sys/ioctl.h> |
| + | |
| + | FILE *cin; |
| + | struct termios initial_settings, new_settings; |
| + | |
| + | void gotsig(int sig) { |
| + | tcsetattr(fileno(cin), TCSANOW, &initial_settings); |
| + | exit( TRUE); |
| + | } |
| + | #endif |
| extern int more_main(int argc, char **argv) | |
| { | |
| - | int c, lines=0; |
| + | int c, lines=0, input; |
| int next_page=0, rows = 24; | |
| - | #ifdef ERASE_STUFF |
| - | int cols=79; |
| + | #ifdef BB_MORE_TERM |
| + | int cols; |
| + | struct winsize win; |
| #endif | |
| struct stat st; | |
| FILE *file = stdin; | |
| if ( strcmp(*argv,"--help")==0 || strcmp(*argv,"-h")==0 ) { | |
| fprintf(stderr, "Usage: %s %s", *argv, more_usage); | |
| - | return(FALSE); |
| + | exit(FALSE); |
| } | |
| argc--; | |
| argv++; | |
| @@ -48,23 +69,47 @@ extern int more_main(int argc, char **argv) | |
| file = fopen(*argv, "r"); | |
| if (file == NULL) { | |
| perror("Can't open file"); | |
| - | return(FALSE); |
| + | exit(FALSE); |
| } | |
| fstat(fileno(file), &st); | |
| fprintf(stderr, "hi\n"); | |
| + | #ifdef BB_MORE_TERM |
| + | cin = fopen("/dev/tty", "r"); |
| + | tcgetattr(fileno(cin),&initial_settings); |
| + | new_settings = initial_settings; |
| + | new_settings.c_lflag &= ~ICANON; |
| + | new_settings.c_lflag &= ~ECHO; |
| + | tcsetattr(fileno(cin), TCSANOW, &new_settings); |
| + | |
| + | (void) signal(SIGINT, gotsig); |
| + | |
| + | ioctl(STDOUT_FILENO, TIOCGWINSZ, &win); |
| + | if (win.ws_row > 4) rows = win.ws_row - 2; |
| + | if (win.ws_col > 0) cols = win.ws_col - 1; |
| + | |
| + | |
| + | #endif |
| while ((c = getc(file)) != EOF) { | |
| if ( next_page ) { | |
| int len=0; | |
| next_page = 0; | |
| lines=0; | |
| - | len = fprintf(stdout, "--More-- (%d%% of %ld bytes)", |
| + | len = fprintf(stdout, "--More-- (%d%% of %ld bytes)%s", |
| (int) (100*( (double) ftell(file) / (double) st.st_size )), | |
| - | st.st_size); |
| + | st.st_size, |
| + | #ifdef BB_MORE_TERM |
| + | "" |
| + | #else |
| + | "\n" |
| + | #endif |
| + | ); |
| + | |
| fflush(stdout); | |
| - | getc( stdin); |
| - | #ifdef ERASE_STUFF |
| - | /* Try to erase the "More" message */ |
| + | input = getc( stdin); |
| + | |
| + | #ifdef BB_MORE_TERM |
| + | /* Erase the "More" message */ |
| while(len-- > 0) | |
| putc('\b', stdout); | |
| while(len++ < cols) | |
| @@ -73,7 +118,12 @@ extern int more_main(int argc, char **argv) | |
| putc('\b', stdout); | |
| fflush(stdout); | |
| #endif | |
| + | |
| } | |
| + | if (input=='q') |
| + | goto end; |
| + | if (input==' ' && c == '\n' ) |
| + | next_page = 1; |
| if ( c == '\n' && ++lines == (rows + 1) ) | |
| next_page = 1; | |
| putc(c, stdout); | |
| @@ -84,7 +134,10 @@ extern int more_main(int argc, char **argv) | |
| argc--; | |
| argv++; | |
| } | |
| - | return(TRUE); |
| + | end: |
| + | #ifdef BB_MORE_TERM |
| + | gotsig(0); |
| + | #endif |
| + | exit(TRUE); |
| } | |
| - | |