More stuff...
This commit is contained in:
parent
2ce1edcf54
commit
3cf52d1958
234
archival/tar.c
234
archival/tar.c
@ -7,7 +7,7 @@
|
|||||||
* This allows creation, extraction, and listing of tar files.
|
* This allows creation, extraction, and listing of tar files.
|
||||||
*
|
*
|
||||||
* Permission to distribute this code under the GPL has been granted.
|
* Permission to distribute this code under the GPL has been granted.
|
||||||
* Modified for busybox by Erik Andersen <andersee@debian.org> <andersen@lineo.com>
|
* Modified for busybox by Erik Andersen <andersee@debian.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@ -42,8 +42,7 @@ const char tar_usage[] =
|
|||||||
* This structure is always embedded in a TAR_BLOCK_SIZE sized block
|
* This structure is always embedded in a TAR_BLOCK_SIZE sized block
|
||||||
* with zero padding. We only process this information minimally.
|
* with zero padding. We only process this information minimally.
|
||||||
*/
|
*/
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
char name[TAR_NAME_SIZE];
|
char name[TAR_NAME_SIZE];
|
||||||
char mode[8];
|
char mode[8];
|
||||||
char uid[8];
|
char uid[8];
|
||||||
@ -125,26 +124,23 @@ static void saveDirectory(const char * fileName,
|
|||||||
static int wantFileName (const char *fileName,
|
static int wantFileName (const char *fileName,
|
||||||
int fileCount, char **fileTable);
|
int fileCount, char **fileTable);
|
||||||
|
|
||||||
static void writeHeader(const char * fileName,
|
static void writeHeader (const char *fileName, const struct stat *statbuf);
|
||||||
const struct stat * statbuf);
|
|
||||||
|
|
||||||
static void writeTarFile (int fileCount, char **fileTable);
|
static void writeTarFile (int fileCount, char **fileTable);
|
||||||
static void writeTarBlock (const char *buf, int len);
|
static void writeTarBlock (const char *buf, int len);
|
||||||
static int putOctal (char *cp, int len, long value);
|
static int putOctal (char *cp, int len, long value);
|
||||||
|
|
||||||
|
|
||||||
extern int
|
extern int tar_main (int argc, char **argv)
|
||||||
tar_main(int argc, char ** argv)
|
|
||||||
{
|
{
|
||||||
const char *options;
|
const char *options;
|
||||||
|
|
||||||
argc--;
|
argc--;
|
||||||
argv++;
|
argv++;
|
||||||
|
|
||||||
if (argc < 1)
|
if (argc < 1) {
|
||||||
{
|
|
||||||
fprintf (stderr, "%s", tar_usage);
|
fprintf (stderr, "%s", tar_usage);
|
||||||
return 1;
|
exit (FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -166,16 +162,13 @@ tar_main(int argc, char ** argv)
|
|||||||
argc--;
|
argc--;
|
||||||
|
|
||||||
if (**argv == '-') {
|
if (**argv == '-') {
|
||||||
for (; *options; options++)
|
for (; *options; options++) {
|
||||||
{
|
switch (*options) {
|
||||||
switch (*options)
|
|
||||||
{
|
|
||||||
case 'f':
|
case 'f':
|
||||||
if (tarName != NULL)
|
if (tarName != NULL) {
|
||||||
{
|
|
||||||
fprintf (stderr, "Only one 'f' option allowed\n");
|
fprintf (stderr, "Only one 'f' option allowed\n");
|
||||||
|
|
||||||
return 1;
|
exit (FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
tarName = *argv++;
|
tarName = *argv++;
|
||||||
@ -209,7 +202,7 @@ tar_main(int argc, char ** argv)
|
|||||||
default:
|
default:
|
||||||
fprintf (stderr, "Unknown tar flag '%c'\n", *options);
|
fprintf (stderr, "Unknown tar flag '%c'\n", *options);
|
||||||
|
|
||||||
return 1;
|
exit (FALSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -217,11 +210,11 @@ tar_main(int argc, char ** argv)
|
|||||||
/*
|
/*
|
||||||
* Validate the options.
|
* Validate the options.
|
||||||
*/
|
*/
|
||||||
if (extractFlag + listFlag + createFlag != 1)
|
if (extractFlag + listFlag + createFlag != 1) {
|
||||||
{
|
fprintf (stderr,
|
||||||
fprintf(stderr, "Exactly one of 'c', 'x' or 't' must be specified\n");
|
"Exactly one of 'c', 'x' or 't' must be specified\n");
|
||||||
|
|
||||||
return 1;
|
exit (FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -234,7 +227,7 @@ tar_main(int argc, char ** argv)
|
|||||||
readTarFile (argc, argv);
|
readTarFile (argc, argv);
|
||||||
if (errorFlag)
|
if (errorFlag)
|
||||||
fprintf (stderr, "\n");
|
fprintf (stderr, "\n");
|
||||||
return( errorFlag);
|
exit (errorFlag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -242,8 +235,7 @@ tar_main(int argc, char ** argv)
|
|||||||
* Read a tar file and extract or list the specified files within it.
|
* 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.
|
* If the list is empty than all files are extracted or listed.
|
||||||
*/
|
*/
|
||||||
static void
|
static void readTarFile (int fileCount, char **fileTable)
|
||||||
readTarFile(int fileCount, char ** fileTable)
|
|
||||||
{
|
{
|
||||||
const char *cp;
|
const char *cp;
|
||||||
int cc;
|
int cc;
|
||||||
@ -267,12 +259,10 @@ readTarFile(int fileCount, char ** fileTable)
|
|||||||
*/
|
*/
|
||||||
if ((tarName == NULL) || !strcmp (tarName, "-")) {
|
if ((tarName == NULL) || !strcmp (tarName, "-")) {
|
||||||
tarFd = STDIN;
|
tarFd = STDIN;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
tarFd = open (tarName, O_RDONLY);
|
tarFd = open (tarName, O_RDONLY);
|
||||||
|
|
||||||
if (tarFd < 0)
|
if (tarFd < 0) {
|
||||||
{
|
|
||||||
perror (tarName);
|
perror (tarName);
|
||||||
errorFlag = TRUE;
|
errorFlag = TRUE;
|
||||||
return;
|
return;
|
||||||
@ -282,30 +272,25 @@ readTarFile(int fileCount, char ** fileTable)
|
|||||||
* Read blocks from the file until an end of file header block
|
* 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.)
|
* has been seen. (A real end of file from a read is an error.)
|
||||||
*/
|
*/
|
||||||
while (!eofFlag)
|
while (!eofFlag) {
|
||||||
{
|
|
||||||
/*
|
/*
|
||||||
* Read the next block of data if necessary.
|
* Read the next block of data if necessary.
|
||||||
* This will be a large block if possible, which we will
|
* This will be a large block if possible, which we will
|
||||||
* then process in the small tar blocks.
|
* then process in the small tar blocks.
|
||||||
*/
|
*/
|
||||||
if (inCc <= 0)
|
if (inCc <= 0) {
|
||||||
{
|
|
||||||
cp = buf;
|
cp = buf;
|
||||||
inCc = fullRead (tarFd, buf, blockSize);
|
inCc = fullRead (tarFd, buf, blockSize);
|
||||||
|
|
||||||
if (inCc < 0)
|
if (inCc < 0) {
|
||||||
{
|
|
||||||
perror (tarName);
|
perror (tarName);
|
||||||
errorFlag = TRUE;
|
errorFlag = TRUE;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inCc == 0)
|
if (inCc == 0) {
|
||||||
{
|
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
"Unexpected end of file from \"%s\"",
|
"Unexpected end of file from \"%s\"", tarName);
|
||||||
tarName);
|
|
||||||
errorFlag = TRUE;
|
errorFlag = TRUE;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
@ -314,8 +299,7 @@ readTarFile(int fileCount, char ** fileTable)
|
|||||||
/*
|
/*
|
||||||
* If we are expecting a header block then examine it.
|
* If we are expecting a header block then examine it.
|
||||||
*/
|
*/
|
||||||
if (inHeader)
|
if (inHeader) {
|
||||||
{
|
|
||||||
readHeader ((const TarHeader *) cp, fileCount, fileTable);
|
readHeader ((const TarHeader *) cp, fileCount, fileTable);
|
||||||
|
|
||||||
cp += TAR_BLOCK_SIZE;
|
cp += TAR_BLOCK_SIZE;
|
||||||
@ -392,10 +376,8 @@ readHeader(const TarHeader * hp, int fileCount, char ** fileTable)
|
|||||||
*/
|
*/
|
||||||
name = hp->name;
|
name = hp->name;
|
||||||
|
|
||||||
if (*name == '\0')
|
if (*name == '\0') {
|
||||||
{
|
for (cc = TAR_BLOCK_SIZE; cc > 0; cc--) {
|
||||||
for (cc = TAR_BLOCK_SIZE; cc > 0; cc--)
|
|
||||||
{
|
|
||||||
if (*name++)
|
if (*name++)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -416,8 +398,7 @@ readHeader(const TarHeader * hp, int fileCount, char ** fileTable)
|
|||||||
mtime = getOctal (hp->mtime, sizeof (hp->mtime));
|
mtime = getOctal (hp->mtime, sizeof (hp->mtime));
|
||||||
checkSum = getOctal (hp->checkSum, sizeof (hp->checkSum));
|
checkSum = getOctal (hp->checkSum, sizeof (hp->checkSum));
|
||||||
|
|
||||||
if ((mode < 0) || (uid < 0) || (gid < 0) || (size < 0))
|
if ((mode < 0) || (uid < 0) || (gid < 0) || (size < 0)) {
|
||||||
{
|
|
||||||
if (!badHeader)
|
if (!badHeader)
|
||||||
fprintf (stderr, "Bad tar header, skipping\n");
|
fprintf (stderr, "Bad tar header, skipping\n");
|
||||||
|
|
||||||
@ -450,13 +431,11 @@ readHeader(const TarHeader * hp, int fileCount, char ** fileTable)
|
|||||||
* Check for absolute paths in the file.
|
* Check for absolute paths in the file.
|
||||||
* If we find any, then warn the user and make them relative.
|
* If we find any, then warn the user and make them relative.
|
||||||
*/
|
*/
|
||||||
if (*name == '/')
|
if (*name == '/') {
|
||||||
{
|
|
||||||
while (*name == '/')
|
while (*name == '/')
|
||||||
name++;
|
name++;
|
||||||
|
|
||||||
if (!warnedRoot)
|
if (!warnedRoot) {
|
||||||
{
|
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
"Absolute path detected, removing leading slashes\n");
|
"Absolute path detected, removing leading slashes\n");
|
||||||
}
|
}
|
||||||
@ -468,10 +447,8 @@ readHeader(const TarHeader * hp, int fileCount, char ** fileTable)
|
|||||||
* See if we want this file to be restored.
|
* See if we want this file to be restored.
|
||||||
* If not, then set up to skip it.
|
* If not, then set up to skip it.
|
||||||
*/
|
*/
|
||||||
if (!wantFileName(name, fileCount, fileTable))
|
if (!wantFileName (name, fileCount, fileTable)) {
|
||||||
{
|
if (!hardLink && !softLink && S_ISREG (mode)) {
|
||||||
if (!hardLink && !softLink && S_ISREG(mode))
|
|
||||||
{
|
|
||||||
inHeader = (size == 0);
|
inHeader = (size == 0);
|
||||||
dataCc = size;
|
dataCc = size;
|
||||||
}
|
}
|
||||||
@ -485,22 +462,18 @@ readHeader(const TarHeader * hp, int fileCount, char ** fileTable)
|
|||||||
* This file is to be handled.
|
* This file is to be handled.
|
||||||
* If we aren't extracting then just list information about the file.
|
* If we aren't extracting then just list information about the file.
|
||||||
*/
|
*/
|
||||||
if (!extractFlag)
|
if (!extractFlag) {
|
||||||
{
|
if (verboseFlag) {
|
||||||
if (verboseFlag)
|
|
||||||
{
|
|
||||||
printf ("%s %3d/%-d %9ld %s %s", modeString (mode),
|
printf ("%s %3d/%-d %9ld %s %s", modeString (mode),
|
||||||
uid, gid, size, timeString (mtime), name);
|
uid, gid, size, timeString (mtime), name);
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
printf ("%s", name);
|
printf ("%s", name);
|
||||||
|
|
||||||
if (hardLink)
|
if (hardLink)
|
||||||
printf (" (link to \"%s\")", hp->linkName);
|
printf (" (link to \"%s\")", hp->linkName);
|
||||||
else if (softLink)
|
else if (softLink)
|
||||||
printf (" (symlink to \"%s\")", hp->linkName);
|
printf (" (symlink to \"%s\")", hp->linkName);
|
||||||
else if (S_ISREG(mode))
|
else if (S_ISREG (mode)) {
|
||||||
{
|
|
||||||
inHeader = (size == 0);
|
inHeader = (size == 0);
|
||||||
dataCc = size;
|
dataCc = size;
|
||||||
}
|
}
|
||||||
@ -516,16 +489,14 @@ readHeader(const TarHeader * hp, int fileCount, char ** fileTable)
|
|||||||
if (verboseFlag)
|
if (verboseFlag)
|
||||||
printf ("x %s\n", name);
|
printf ("x %s\n", name);
|
||||||
|
|
||||||
if (hardLink)
|
if (hardLink) {
|
||||||
{
|
|
||||||
if (link (hp->linkName, name) < 0)
|
if (link (hp->linkName, name) < 0)
|
||||||
perror (name);
|
perror (name);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (softLink)
|
if (softLink) {
|
||||||
{
|
|
||||||
#ifdef S_ISLNK
|
#ifdef S_ISLNK
|
||||||
if (symlink (hp->linkName, name) < 0)
|
if (symlink (hp->linkName, name) < 0)
|
||||||
perror (name);
|
perror (name);
|
||||||
@ -538,8 +509,7 @@ readHeader(const TarHeader * hp, int fileCount, char ** fileTable)
|
|||||||
/*
|
/*
|
||||||
* If the file is a directory, then just create the path.
|
* If the file is a directory, then just create the path.
|
||||||
*/
|
*/
|
||||||
if (S_ISDIR(mode))
|
if (S_ISDIR (mode)) {
|
||||||
{
|
|
||||||
createPath (name, mode);
|
createPath (name, mode);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -562,8 +532,7 @@ readHeader(const TarHeader * hp, int fileCount, char ** fileTable)
|
|||||||
else
|
else
|
||||||
outFd = open (name, O_WRONLY | O_CREAT | O_TRUNC, mode);
|
outFd = open (name, O_WRONLY | O_CREAT | O_TRUNC, mode);
|
||||||
|
|
||||||
if (outFd < 0)
|
if (outFd < 0) {
|
||||||
{
|
|
||||||
perror (name);
|
perror (name);
|
||||||
skipFileFlag = TRUE;
|
skipFileFlag = TRUE;
|
||||||
return;
|
return;
|
||||||
@ -572,8 +541,7 @@ readHeader(const TarHeader * hp, int fileCount, char ** fileTable)
|
|||||||
/*
|
/*
|
||||||
* If the file is empty, then that's all we need to do.
|
* If the file is empty, then that's all we need to do.
|
||||||
*/
|
*/
|
||||||
if (size == 0 && tostdoutFlag == FALSE)
|
if (size == 0 && tostdoutFlag == FALSE) {
|
||||||
{
|
|
||||||
(void) close (outFd);
|
(void) close (outFd);
|
||||||
outFd = -1;
|
outFd = -1;
|
||||||
}
|
}
|
||||||
@ -583,8 +551,7 @@ readHeader(const TarHeader * hp, int fileCount, char ** fileTable)
|
|||||||
/*
|
/*
|
||||||
* Handle a data block of some specified size that was read.
|
* Handle a data block of some specified size that was read.
|
||||||
*/
|
*/
|
||||||
static void
|
static void readData (const char *cp, int count)
|
||||||
readData(const char * cp, int count)
|
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Reduce the amount of data left in this file.
|
* Reduce the amount of data left in this file.
|
||||||
@ -606,8 +573,7 @@ readData(const char * cp, int count)
|
|||||||
/*
|
/*
|
||||||
* Write the data to the output file.
|
* Write the data to the output file.
|
||||||
*/
|
*/
|
||||||
if (fullWrite(outFd, cp, count) < 0)
|
if (fullWrite (outFd, cp, count) < 0) {
|
||||||
{
|
|
||||||
perror (outName);
|
perror (outName);
|
||||||
if (tostdoutFlag == FALSE) {
|
if (tostdoutFlag == FALSE) {
|
||||||
(void) close (outFd);
|
(void) close (outFd);
|
||||||
@ -621,8 +587,7 @@ readData(const char * cp, int count)
|
|||||||
* If the write failed, close the file and disable further
|
* If the write failed, close the file and disable further
|
||||||
* writes to this file.
|
* writes to this file.
|
||||||
*/
|
*/
|
||||||
if (dataCc <= 0 && tostdoutFlag==FALSE)
|
if (dataCc <= 0 && tostdoutFlag == FALSE) {
|
||||||
{
|
|
||||||
if (close (outFd))
|
if (close (outFd))
|
||||||
perror (outName);
|
perror (outName);
|
||||||
|
|
||||||
@ -634,16 +599,14 @@ readData(const char * cp, int count)
|
|||||||
/*
|
/*
|
||||||
* Write a tar file containing the specified files.
|
* Write a tar file containing the specified files.
|
||||||
*/
|
*/
|
||||||
static void
|
static void writeTarFile (int fileCount, char **fileTable)
|
||||||
writeTarFile(int fileCount, char ** fileTable)
|
|
||||||
{
|
{
|
||||||
struct stat statbuf;
|
struct stat statbuf;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make sure there is at least one file specified.
|
* Make sure there is at least one file specified.
|
||||||
*/
|
*/
|
||||||
if (fileCount <= 0)
|
if (fileCount <= 0) {
|
||||||
{
|
|
||||||
fprintf (stderr, "No files specified to be saved\n");
|
fprintf (stderr, "No files specified to be saved\n");
|
||||||
errorFlag = TRUE;
|
errorFlag = TRUE;
|
||||||
}
|
}
|
||||||
@ -654,12 +617,10 @@ writeTarFile(int fileCount, char ** fileTable)
|
|||||||
if ((tarName == NULL) || !strcmp (tarName, "-")) {
|
if ((tarName == NULL) || !strcmp (tarName, "-")) {
|
||||||
tostdoutFlag = TRUE;
|
tostdoutFlag = TRUE;
|
||||||
tarFd = STDOUT;
|
tarFd = STDOUT;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
tarFd = open (tarName, O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
tarFd = open (tarName, O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
||||||
|
|
||||||
if (tarFd < 0)
|
if (tarFd < 0) {
|
||||||
{
|
|
||||||
perror (tarName);
|
perror (tarName);
|
||||||
errorFlag = TRUE;
|
errorFlag = TRUE;
|
||||||
return;
|
return;
|
||||||
@ -668,8 +629,7 @@ writeTarFile(int fileCount, char ** fileTable)
|
|||||||
/*
|
/*
|
||||||
* Get the device and inode of the tar file for checking later.
|
* Get the device and inode of the tar file for checking later.
|
||||||
*/
|
*/
|
||||||
if (fstat(tarFd, &statbuf) < 0)
|
if (fstat (tarFd, &statbuf) < 0) {
|
||||||
{
|
|
||||||
perror (tarName);
|
perror (tarName);
|
||||||
errorFlag = TRUE;
|
errorFlag = TRUE;
|
||||||
goto done;
|
goto done;
|
||||||
@ -682,8 +642,7 @@ writeTarFile(int fileCount, char ** fileTable)
|
|||||||
* Append each file name into the archive file.
|
* Append each file name into the archive file.
|
||||||
* Follow symbolic links for these top level file names.
|
* Follow symbolic links for these top level file names.
|
||||||
*/
|
*/
|
||||||
while (!errorFlag && (fileCount-- > 0))
|
while (!errorFlag && (fileCount-- > 0)) {
|
||||||
{
|
|
||||||
saveFile (*fileTable++, FALSE);
|
saveFile (*fileTable++, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -709,8 +668,7 @@ done:
|
|||||||
* flag indicates whether or not we want to see symbolic links as
|
* flag indicates whether or not we want to see symbolic links as
|
||||||
* they really are, instead of blindly following them.
|
* they really are, instead of blindly following them.
|
||||||
*/
|
*/
|
||||||
static void
|
static void saveFile (const char *fileName, int seeLinks)
|
||||||
saveFile(const char * fileName, int seeLinks)
|
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
int mode;
|
int mode;
|
||||||
@ -722,8 +680,7 @@ saveFile(const char * fileName, int seeLinks)
|
|||||||
/*
|
/*
|
||||||
* Check that the file name will fit in the header.
|
* Check that the file name will fit in the header.
|
||||||
*/
|
*/
|
||||||
if (strlen(fileName) >= TAR_NAME_SIZE)
|
if (strlen (fileName) >= TAR_NAME_SIZE) {
|
||||||
{
|
|
||||||
fprintf (stderr, "%s: File name is too long\n", fileName);
|
fprintf (stderr, "%s: File name is too long\n", fileName);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -739,8 +696,7 @@ saveFile(const char * fileName, int seeLinks)
|
|||||||
#endif
|
#endif
|
||||||
status = stat (fileName, &statbuf);
|
status = stat (fileName, &statbuf);
|
||||||
|
|
||||||
if (status < 0)
|
if (status < 0) {
|
||||||
{
|
|
||||||
perror (fileName);
|
perror (fileName);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -749,8 +705,7 @@ saveFile(const char * fileName, int seeLinks)
|
|||||||
/*
|
/*
|
||||||
* Make sure we aren't trying to save our file into itself.
|
* Make sure we aren't trying to save our file into itself.
|
||||||
*/
|
*/
|
||||||
if ((statbuf.st_dev == tarDev) && (statbuf.st_ino == tarInode))
|
if ((statbuf.st_dev == tarDev) && (statbuf.st_ino == tarInode)) {
|
||||||
{
|
|
||||||
fprintf (stderr, "Skipping saving of archive file itself\n");
|
fprintf (stderr, "Skipping saving of archive file itself\n");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -761,15 +716,13 @@ saveFile(const char * fileName, int seeLinks)
|
|||||||
*/
|
*/
|
||||||
mode = statbuf.st_mode;
|
mode = statbuf.st_mode;
|
||||||
|
|
||||||
if (S_ISDIR(mode))
|
if (S_ISDIR (mode)) {
|
||||||
{
|
|
||||||
saveDirectory (fileName, &statbuf);
|
saveDirectory (fileName, &statbuf);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (S_ISREG(mode))
|
if (S_ISREG (mode)) {
|
||||||
{
|
|
||||||
saveRegularFile (fileName, &statbuf);
|
saveRegularFile (fileName, &statbuf);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -800,8 +753,7 @@ saveRegularFile(const char * fileName, const struct stat * statbuf)
|
|||||||
*/
|
*/
|
||||||
fileFd = open (fileName, O_RDONLY);
|
fileFd = open (fileName, O_RDONLY);
|
||||||
|
|
||||||
if (fileFd < 0)
|
if (fileFd < 0) {
|
||||||
{
|
|
||||||
perror (fileName);
|
perror (fileName);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -821,8 +773,7 @@ saveRegularFile(const char * fileName, const struct stat * statbuf)
|
|||||||
fullDataCount = statbuf->st_size;
|
fullDataCount = statbuf->st_size;
|
||||||
sawEof = FALSE;
|
sawEof = FALSE;
|
||||||
|
|
||||||
while (fullDataCount > 0)
|
while (fullDataCount > 0) {
|
||||||
{
|
|
||||||
/*
|
/*
|
||||||
* Get the amount to write this iteration which is
|
* Get the amount to write this iteration which is
|
||||||
* the minumum of the amount left to write and the
|
* the minumum of the amount left to write and the
|
||||||
@ -839,12 +790,10 @@ saveRegularFile(const char * fileName, const struct stat * statbuf)
|
|||||||
*/
|
*/
|
||||||
cc = 0;
|
cc = 0;
|
||||||
|
|
||||||
if (!sawEof)
|
if (!sawEof) {
|
||||||
{
|
|
||||||
cc = fullRead (fileFd, data, dataCount);
|
cc = fullRead (fileFd, data, dataCount);
|
||||||
|
|
||||||
if (cc < 0)
|
if (cc < 0) {
|
||||||
{
|
|
||||||
perror (fileName);
|
perror (fileName);
|
||||||
|
|
||||||
(void) close (fileFd);
|
(void) close (fileFd);
|
||||||
@ -857,11 +806,9 @@ saveRegularFile(const char * fileName, const struct stat * statbuf)
|
|||||||
* If the file ended too soon, complain and set
|
* If the file ended too soon, complain and set
|
||||||
* a flag so we will zero fill the rest of it.
|
* a flag so we will zero fill the rest of it.
|
||||||
*/
|
*/
|
||||||
if (cc < dataCount)
|
if (cc < dataCount) {
|
||||||
{
|
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
"%s: Short read - zero filling",
|
"%s: Short read - zero filling", fileName);
|
||||||
fileName);
|
|
||||||
|
|
||||||
sawEof = TRUE;
|
sawEof = TRUE;
|
||||||
}
|
}
|
||||||
@ -892,8 +839,7 @@ saveRegularFile(const char * fileName, const struct stat * statbuf)
|
|||||||
/*
|
/*
|
||||||
* Save a directory and all of its files to the tar file.
|
* Save a directory and all of its files to the tar file.
|
||||||
*/
|
*/
|
||||||
static void
|
static void saveDirectory (const char *dirName, const struct stat *statbuf)
|
||||||
saveDirectory(const char * dirName, const struct stat * statbuf)
|
|
||||||
{
|
{
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
struct dirent *entry;
|
struct dirent *entry;
|
||||||
@ -917,8 +863,7 @@ saveDirectory(const char * dirName, const struct stat * statbuf)
|
|||||||
*/
|
*/
|
||||||
dir = opendir (dirName);
|
dir = opendir (dirName);
|
||||||
|
|
||||||
if (dir == NULL)
|
if (dir == NULL) {
|
||||||
{
|
|
||||||
fprintf (stderr, "Cannot read directory \"%s\": %s\n",
|
fprintf (stderr, "Cannot read directory \"%s\": %s\n",
|
||||||
dirName, strerror (errno));
|
dirName, strerror (errno));
|
||||||
|
|
||||||
@ -934,11 +879,9 @@ saveDirectory(const char * dirName, const struct stat * statbuf)
|
|||||||
* Read all of the directory entries and check them,
|
* Read all of the directory entries and check them,
|
||||||
* except for the current and parent directory entries.
|
* except for the current and parent directory entries.
|
||||||
*/
|
*/
|
||||||
while (!errorFlag && ((entry = readdir(dir)) != NULL))
|
while (!errorFlag && ((entry = readdir (dir)) != NULL)) {
|
||||||
{
|
|
||||||
if ((strcmp (entry->d_name, ".") == 0) ||
|
if ((strcmp (entry->d_name, ".") == 0) ||
|
||||||
(strcmp(entry->d_name, "..") == 0))
|
(strcmp (entry->d_name, "..") == 0)) {
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -970,8 +913,7 @@ saveDirectory(const char * dirName, const struct stat * statbuf)
|
|||||||
* Write a tar header for the specified file name and status.
|
* Write a tar header for the specified file name and status.
|
||||||
* It is assumed that the file name fits.
|
* It is assumed that the file name fits.
|
||||||
*/
|
*/
|
||||||
static void
|
static void writeHeader (const char *fileName, const struct stat *statbuf)
|
||||||
writeHeader(const char * fileName, const struct stat * statbuf)
|
|
||||||
{
|
{
|
||||||
long checkSum;
|
long checkSum;
|
||||||
const unsigned char *cp;
|
const unsigned char *cp;
|
||||||
@ -1027,8 +969,7 @@ writeHeader(const char * fileName, const struct stat * statbuf)
|
|||||||
* The data is always padded out to a multiple of TAR_BLOCK_SIZE.
|
* The data is always padded out to a multiple of TAR_BLOCK_SIZE.
|
||||||
* The errorFlag static variable is set on an error.
|
* The errorFlag static variable is set on an error.
|
||||||
*/
|
*/
|
||||||
static void
|
static void writeTarBlock (const char *buf, int len)
|
||||||
writeTarBlock(const char * buf, int len)
|
|
||||||
{
|
{
|
||||||
int partialLength;
|
int partialLength;
|
||||||
int completeLength;
|
int completeLength;
|
||||||
@ -1049,8 +990,7 @@ writeTarBlock(const char * buf, int len)
|
|||||||
/*
|
/*
|
||||||
* Write all of the complete blocks.
|
* Write all of the complete blocks.
|
||||||
*/
|
*/
|
||||||
if ((completeLength > 0) && !fullWrite(tarFd, buf, completeLength))
|
if ((completeLength > 0) && !fullWrite (tarFd, buf, completeLength)) {
|
||||||
{
|
|
||||||
perror (tarName);
|
perror (tarName);
|
||||||
|
|
||||||
errorFlag = TRUE;
|
errorFlag = TRUE;
|
||||||
@ -1074,8 +1014,7 @@ writeTarBlock(const char * buf, int len)
|
|||||||
/*
|
/*
|
||||||
* Write the last complete block.
|
* Write the last complete block.
|
||||||
*/
|
*/
|
||||||
if (!fullWrite(tarFd, fullBlock, TAR_BLOCK_SIZE))
|
if (!fullWrite (tarFd, fullBlock, TAR_BLOCK_SIZE)) {
|
||||||
{
|
|
||||||
perror (tarName);
|
perror (tarName);
|
||||||
|
|
||||||
errorFlag = TRUE;
|
errorFlag = TRUE;
|
||||||
@ -1089,8 +1028,7 @@ writeTarBlock(const char * buf, int len)
|
|||||||
* while all previous ones get default protections. Errors are not reported
|
* while all previous ones get default protections. Errors are not reported
|
||||||
* here, as failures to restore files can be reported later.
|
* here, as failures to restore files can be reported later.
|
||||||
*/
|
*/
|
||||||
static void
|
static void createPath (const char *name, int mode)
|
||||||
createPath(const char * name, int mode)
|
|
||||||
{
|
{
|
||||||
char *cp;
|
char *cp;
|
||||||
char *cpOld;
|
char *cpOld;
|
||||||
@ -1100,8 +1038,7 @@ createPath(const char * name, int mode)
|
|||||||
|
|
||||||
cp = strchr (buf, '/');
|
cp = strchr (buf, '/');
|
||||||
|
|
||||||
while (cp)
|
while (cp) {
|
||||||
{
|
|
||||||
cpOld = cp;
|
cpOld = cp;
|
||||||
cp = strchr (cp + 1, '/');
|
cp = strchr (cp + 1, '/');
|
||||||
|
|
||||||
@ -1120,13 +1057,11 @@ createPath(const char * name, int mode)
|
|||||||
* spaces on both sides of the number and with an optional null character
|
* spaces on both sides of the number and with an optional null character
|
||||||
* at the end. Returns -1 on an illegal format.
|
* at the end. Returns -1 on an illegal format.
|
||||||
*/
|
*/
|
||||||
static long
|
static long getOctal (const char *cp, int len)
|
||||||
getOctal(const char * cp, int len)
|
|
||||||
{
|
{
|
||||||
long val;
|
long val;
|
||||||
|
|
||||||
while ((len > 0) && (*cp == ' '))
|
while ((len > 0) && (*cp == ' ')) {
|
||||||
{
|
|
||||||
cp++;
|
cp++;
|
||||||
len--;
|
len--;
|
||||||
}
|
}
|
||||||
@ -1136,14 +1071,12 @@ getOctal(const char * cp, int len)
|
|||||||
|
|
||||||
val = 0;
|
val = 0;
|
||||||
|
|
||||||
while ((len > 0) && isOctal(*cp))
|
while ((len > 0) && isOctal (*cp)) {
|
||||||
{
|
|
||||||
val = val * 8 + *cp++ - '0';
|
val = val * 8 + *cp++ - '0';
|
||||||
len--;
|
len--;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((len > 0) && (*cp == ' '))
|
while ((len > 0) && (*cp == ' ')) {
|
||||||
{
|
|
||||||
cp++;
|
cp++;
|
||||||
len--;
|
len--;
|
||||||
}
|
}
|
||||||
@ -1160,8 +1093,7 @@ getOctal(const char * cp, int len)
|
|||||||
* The number is zero and space padded and possibly null padded.
|
* The number is zero and space padded and possibly null padded.
|
||||||
* Returns TRUE if successful.
|
* Returns TRUE if successful.
|
||||||
*/
|
*/
|
||||||
static int
|
static int putOctal (char *cp, int len, long value)
|
||||||
putOctal(char * cp, int len, long value)
|
|
||||||
{
|
{
|
||||||
int tempLength;
|
int tempLength;
|
||||||
char *tempString;
|
char *tempString;
|
||||||
@ -1180,8 +1112,7 @@ putOctal(char * cp, int len, long value)
|
|||||||
/*
|
/*
|
||||||
* If the string is too large, suppress the leading space.
|
* If the string is too large, suppress the leading space.
|
||||||
*/
|
*/
|
||||||
if (tempLength > len)
|
if (tempLength > len) {
|
||||||
{
|
|
||||||
tempLength--;
|
tempLength--;
|
||||||
tempString++;
|
tempString++;
|
||||||
}
|
}
|
||||||
@ -1230,8 +1161,7 @@ wantFileName(const char * fileName, int fileCount, char ** fileTable)
|
|||||||
/*
|
/*
|
||||||
* Check each of the test paths.
|
* Check each of the test paths.
|
||||||
*/
|
*/
|
||||||
while (fileCount-- > 0)
|
while (fileCount-- > 0) {
|
||||||
{
|
|
||||||
pathName = *fileTable++;
|
pathName = *fileTable++;
|
||||||
|
|
||||||
pathLength = strlen (pathName);
|
pathLength = strlen (pathName);
|
||||||
@ -1242,9 +1172,7 @@ wantFileName(const char * fileName, int fileCount, char ** fileTable)
|
|||||||
if (memcmp (fileName, pathName, pathLength) != 0)
|
if (memcmp (fileName, pathName, pathLength) != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((fileLength == pathLength) ||
|
if ((fileLength == pathLength) || (fileName[pathLength] == '/')) {
|
||||||
(fileName[pathLength] == '/'))
|
|
||||||
{
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1256,5 +1184,3 @@ wantFileName(const char * fileName, int fileCount, char ** fileTable)
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
/* END CODE */
|
/* END CODE */
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
//#define BB_DESCEND
|
//#define BB_DESCEND
|
||||||
#define BB_DF
|
#define BB_DF
|
||||||
#define BB_DMESG
|
#define BB_DMESG
|
||||||
//#define BB_DUTMP
|
#define BB_DUTMP
|
||||||
//#define BB_DYADIC
|
//#define BB_DYADIC
|
||||||
#define BB_FALSE
|
#define BB_FALSE
|
||||||
//#define BB_FDFLUSH
|
//#define BB_FDFLUSH
|
||||||
@ -24,7 +24,7 @@
|
|||||||
#define BB_GREP
|
#define BB_GREP
|
||||||
////#define BB_HALT
|
////#define BB_HALT
|
||||||
//#define BB_INIT
|
//#define BB_INIT
|
||||||
//#define BB_KILL
|
#define BB_KILL
|
||||||
////#define BB_LENGTH
|
////#define BB_LENGTH
|
||||||
//#define BB_LN
|
//#define BB_LN
|
||||||
//#define BB_LOADKMAP
|
//#define BB_LOADKMAP
|
||||||
@ -44,10 +44,10 @@
|
|||||||
//#define BB_POSTPROCESS
|
//#define BB_POSTPROCESS
|
||||||
//#define BB_PRINTF
|
//#define BB_PRINTF
|
||||||
#define BB_PWD
|
#define BB_PWD
|
||||||
//#define BB_REBOOT
|
#define BB_REBOOT
|
||||||
//#define BB_RM
|
//#define BB_RM
|
||||||
//#define BB_RMDIR
|
//#define BB_RMDIR
|
||||||
//#define BB_SLEEP
|
#define BB_SLEEP
|
||||||
////#define BB_SWAPOFF
|
////#define BB_SWAPOFF
|
||||||
//#define BB_SWAPON
|
//#define BB_SWAPON
|
||||||
//#define BB_SYNC
|
//#define BB_SYNC
|
||||||
|
28
cat.c
28
cat.c
@ -22,15 +22,27 @@
|
|||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
const char cat_usage[] = "[file ...]";
|
|
||||||
|
static void print_file( FILE *file)
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
while ((c = getc(file)) != EOF)
|
||||||
|
putc(c, stdout);
|
||||||
|
fclose(file);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
extern int cat_more_main(int argc, char **argv)
|
extern int cat_more_main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int c;
|
FILE *file;
|
||||||
FILE *file = stdin;
|
|
||||||
|
|
||||||
if ( (argc < 2) || (**(argv+1) == '-') ) {
|
if (argc==1) {
|
||||||
fprintf(stderr, "Usage: %s %s", *argv, cat_usage);
|
print_file( stdin);
|
||||||
|
exit( TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( **(argv+1) == '-' ) {
|
||||||
|
fprintf(stderr, "Usage: cat [file ...]\n");
|
||||||
exit(FALSE);
|
exit(FALSE);
|
||||||
}
|
}
|
||||||
argc--;
|
argc--;
|
||||||
@ -42,11 +54,7 @@ extern int cat_more_main(int argc, char **argv)
|
|||||||
perror(*argv);
|
perror(*argv);
|
||||||
exit(FALSE);
|
exit(FALSE);
|
||||||
}
|
}
|
||||||
while ((c = getc(file)) != EOF)
|
print_file( file);
|
||||||
putc(c, stdout);
|
|
||||||
fclose(file);
|
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
argc--;
|
argc--;
|
||||||
argv++;
|
argv++;
|
||||||
}
|
}
|
||||||
|
@ -22,15 +22,27 @@
|
|||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
const char cat_usage[] = "[file ...]";
|
|
||||||
|
static void print_file( FILE *file)
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
while ((c = getc(file)) != EOF)
|
||||||
|
putc(c, stdout);
|
||||||
|
fclose(file);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
extern int cat_more_main(int argc, char **argv)
|
extern int cat_more_main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int c;
|
FILE *file;
|
||||||
FILE *file = stdin;
|
|
||||||
|
|
||||||
if ( (argc < 2) || (**(argv+1) == '-') ) {
|
if (argc==1) {
|
||||||
fprintf(stderr, "Usage: %s %s", *argv, cat_usage);
|
print_file( stdin);
|
||||||
|
exit( TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( **(argv+1) == '-' ) {
|
||||||
|
fprintf(stderr, "Usage: cat [file ...]\n");
|
||||||
exit(FALSE);
|
exit(FALSE);
|
||||||
}
|
}
|
||||||
argc--;
|
argc--;
|
||||||
@ -42,11 +54,7 @@ extern int cat_more_main(int argc, char **argv)
|
|||||||
perror(*argv);
|
perror(*argv);
|
||||||
exit(FALSE);
|
exit(FALSE);
|
||||||
}
|
}
|
||||||
while ((c = getc(file)) != EOF)
|
print_file( file);
|
||||||
putc(c, stdout);
|
|
||||||
fclose(file);
|
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
argc--;
|
argc--;
|
||||||
argv++;
|
argv++;
|
||||||
}
|
}
|
||||||
|
389
coreutils/dd.c
389
coreutils/dd.c
@ -6,11 +6,13 @@
|
|||||||
* The "dd" command, originally taken from sash.
|
* The "dd" command, originally taken from sash.
|
||||||
*
|
*
|
||||||
* Permission to distribute this code under the GPL has been granted.
|
* Permission to distribute this code under the GPL has been granted.
|
||||||
* Majorly modified, and bugs fixed for busybox by Erik Andersen <andersee@debian.org> <andersen@lineo.com>
|
* Mostly rewritten and bugs fixed for busybox by Erik Andersen <andersee@debian.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#ifdef BB_DD
|
#include <stdio.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
const char dd_usage[] =
|
const char dd_usage[] =
|
||||||
"Copy a file, converting and formatting according to options\n\
|
"Copy a file, converting and formatting according to options\n\
|
||||||
@ -20,250 +22,18 @@ usage: [if=name] [of=name] [bs=n] [count=n]\n\
|
|||||||
\tof=FILE\twrite to FILE instead of stout\n\
|
\tof=FILE\twrite to FILE instead of stout\n\
|
||||||
\tbs=n\tread and write N bytes at a time\n\
|
\tbs=n\tread and write N bytes at a time\n\
|
||||||
\tcount=n\tcopy only n input blocks\n\
|
\tcount=n\tcopy only n input blocks\n\
|
||||||
|
\tskip=n\tskip n input blocks\n\
|
||||||
\n\
|
\n\
|
||||||
BYTES may be suffixed: by k for x1024, b for x512, and w for x2.\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
|
|
||||||
{
|
|
||||||
const char * name;
|
|
||||||
int value;
|
|
||||||
} PARAM;
|
|
||||||
|
|
||||||
|
|
||||||
static const PARAM params[] =
|
|
||||||
{
|
|
||||||
{"if", PAR_IF},
|
|
||||||
{"of", PAR_OF},
|
|
||||||
{"bs", PAR_BS},
|
|
||||||
{"count", PAR_COUNT},
|
|
||||||
{NULL, PAR_NONE}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static long getNum(const char * cp);
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
buf = localBuf;
|
|
||||||
|
|
||||||
if (blockSize > sizeof(localBuf))
|
|
||||||
{
|
|
||||||
buf = malloc(blockSize);
|
|
||||||
|
|
||||||
if (buf == NULL)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Cannot allocate buffer\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
intotal = 0;
|
|
||||||
outTotal = 0;
|
|
||||||
|
|
||||||
if (inFile == NULL)
|
|
||||||
inFd = STDIN;
|
|
||||||
else
|
|
||||||
inFd = open(inFile, 0);
|
|
||||||
|
|
||||||
if (inFd < 0)
|
|
||||||
{
|
|
||||||
perror(inFile);
|
|
||||||
|
|
||||||
if (buf != localBuf)
|
|
||||||
free(buf);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (outFile == NULL)
|
|
||||||
outFd = STDOUT;
|
|
||||||
else
|
|
||||||
outFd = creat(outFile, 0666);
|
|
||||||
|
|
||||||
if (outFd < 0)
|
|
||||||
{
|
|
||||||
perror(outFile);
|
|
||||||
close(inFd);
|
|
||||||
|
|
||||||
if (buf != localBuf)
|
|
||||||
free(buf);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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.
|
* Read a number with a possible multiplier.
|
||||||
* Returns -1 if the number format is illegal.
|
* Returns -1 if the number format is illegal.
|
||||||
*/
|
*/
|
||||||
static long
|
static long getNum (const char *cp)
|
||||||
getNum(const char * cp)
|
|
||||||
{
|
{
|
||||||
long value;
|
long value;
|
||||||
|
|
||||||
@ -275,8 +45,7 @@ getNum(const char * cp)
|
|||||||
while (isDecimal (*cp))
|
while (isDecimal (*cp))
|
||||||
value = value * 10 + *cp++ - '0';
|
value = value * 10 + *cp++ - '0';
|
||||||
|
|
||||||
switch (*cp++)
|
switch (*cp++) {
|
||||||
{
|
|
||||||
case 'k':
|
case 'k':
|
||||||
value *= 1024;
|
value *= 1024;
|
||||||
break;
|
break;
|
||||||
@ -302,6 +71,146 @@ getNum(const char * cp)
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
/* END CODE */
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fprintf (stderr, "Got here. argv=%s\n", *argv);
|
||||||
|
goto usage;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inCc < 0)
|
||||||
|
perror (inFile);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
close (inFd);
|
||||||
|
close (outFd);
|
||||||
|
free (buf);
|
||||||
|
|
||||||
|
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:
|
||||||
|
|
||||||
|
fprintf (stderr, "%s", dd_usage);
|
||||||
|
exit( FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
|
||||||
const char pwd_usage[] = "Print the current directory.\n";
|
const char pwd_usage[] = "Print the current directory.\n";
|
||||||
|
|
||||||
extern int
|
extern int
|
||||||
pwd_main(int argc, char * * argv)
|
pwd_main(int argc, char * * argv)
|
||||||
{
|
{
|
||||||
char buf[1024];
|
char buf[NAME_MAX];
|
||||||
|
|
||||||
if ( getcwd(buf, sizeof(buf)) == NULL ) {
|
if ( getcwd(buf, sizeof(buf)) == NULL ) {
|
||||||
perror("get working directory");
|
perror("get working directory");
|
||||||
|
@ -1,15 +1,20 @@
|
|||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
const char sleep_usage[] = "sleep seconds\n"
|
const char sleep_usage[] = " NUMBER\n"
|
||||||
"\n"
|
"Pause for NUMBER seconds.\n";
|
||||||
"\tPause program execution for the given number of seconds.\n";
|
|
||||||
|
|
||||||
extern int
|
extern int
|
||||||
sleep_main(struct FileInfo * i, int argc, char * * argv)
|
sleep_main(int argc, char * * argv)
|
||||||
{
|
{
|
||||||
if ( sleep(atoi(argv[1])) != 0 )
|
if ( (argc < 2) || (**(argv+1) == '-') ) {
|
||||||
return -1;
|
fprintf(stderr, "Usage: %s %s", *argv, sleep_usage);
|
||||||
else
|
exit(FALSE);
|
||||||
return 0;
|
}
|
||||||
|
|
||||||
|
if ( sleep(atoi(*(++argv))) != 0 ) {
|
||||||
|
perror( "sleep");
|
||||||
|
exit (FALSE);
|
||||||
|
} else
|
||||||
|
exit (TRUE);
|
||||||
}
|
}
|
||||||
|
389
dd.c
389
dd.c
@ -6,11 +6,13 @@
|
|||||||
* The "dd" command, originally taken from sash.
|
* The "dd" command, originally taken from sash.
|
||||||
*
|
*
|
||||||
* Permission to distribute this code under the GPL has been granted.
|
* Permission to distribute this code under the GPL has been granted.
|
||||||
* Majorly modified, and bugs fixed for busybox by Erik Andersen <andersee@debian.org> <andersen@lineo.com>
|
* Mostly rewritten and bugs fixed for busybox by Erik Andersen <andersee@debian.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#ifdef BB_DD
|
#include <stdio.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
const char dd_usage[] =
|
const char dd_usage[] =
|
||||||
"Copy a file, converting and formatting according to options\n\
|
"Copy a file, converting and formatting according to options\n\
|
||||||
@ -20,250 +22,18 @@ usage: [if=name] [of=name] [bs=n] [count=n]\n\
|
|||||||
\tof=FILE\twrite to FILE instead of stout\n\
|
\tof=FILE\twrite to FILE instead of stout\n\
|
||||||
\tbs=n\tread and write N bytes at a time\n\
|
\tbs=n\tread and write N bytes at a time\n\
|
||||||
\tcount=n\tcopy only n input blocks\n\
|
\tcount=n\tcopy only n input blocks\n\
|
||||||
|
\tskip=n\tskip n input blocks\n\
|
||||||
\n\
|
\n\
|
||||||
BYTES may be suffixed: by k for x1024, b for x512, and w for x2.\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
|
|
||||||
{
|
|
||||||
const char * name;
|
|
||||||
int value;
|
|
||||||
} PARAM;
|
|
||||||
|
|
||||||
|
|
||||||
static const PARAM params[] =
|
|
||||||
{
|
|
||||||
{"if", PAR_IF},
|
|
||||||
{"of", PAR_OF},
|
|
||||||
{"bs", PAR_BS},
|
|
||||||
{"count", PAR_COUNT},
|
|
||||||
{NULL, PAR_NONE}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static long getNum(const char * cp);
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
buf = localBuf;
|
|
||||||
|
|
||||||
if (blockSize > sizeof(localBuf))
|
|
||||||
{
|
|
||||||
buf = malloc(blockSize);
|
|
||||||
|
|
||||||
if (buf == NULL)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Cannot allocate buffer\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
intotal = 0;
|
|
||||||
outTotal = 0;
|
|
||||||
|
|
||||||
if (inFile == NULL)
|
|
||||||
inFd = STDIN;
|
|
||||||
else
|
|
||||||
inFd = open(inFile, 0);
|
|
||||||
|
|
||||||
if (inFd < 0)
|
|
||||||
{
|
|
||||||
perror(inFile);
|
|
||||||
|
|
||||||
if (buf != localBuf)
|
|
||||||
free(buf);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (outFile == NULL)
|
|
||||||
outFd = STDOUT;
|
|
||||||
else
|
|
||||||
outFd = creat(outFile, 0666);
|
|
||||||
|
|
||||||
if (outFd < 0)
|
|
||||||
{
|
|
||||||
perror(outFile);
|
|
||||||
close(inFd);
|
|
||||||
|
|
||||||
if (buf != localBuf)
|
|
||||||
free(buf);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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.
|
* Read a number with a possible multiplier.
|
||||||
* Returns -1 if the number format is illegal.
|
* Returns -1 if the number format is illegal.
|
||||||
*/
|
*/
|
||||||
static long
|
static long getNum (const char *cp)
|
||||||
getNum(const char * cp)
|
|
||||||
{
|
{
|
||||||
long value;
|
long value;
|
||||||
|
|
||||||
@ -275,8 +45,7 @@ getNum(const char * cp)
|
|||||||
while (isDecimal (*cp))
|
while (isDecimal (*cp))
|
||||||
value = value * 10 + *cp++ - '0';
|
value = value * 10 + *cp++ - '0';
|
||||||
|
|
||||||
switch (*cp++)
|
switch (*cp++) {
|
||||||
{
|
|
||||||
case 'k':
|
case 'k':
|
||||||
value *= 1024;
|
value *= 1024;
|
||||||
break;
|
break;
|
||||||
@ -302,6 +71,146 @@ getNum(const char * cp)
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
/* END CODE */
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fprintf (stderr, "Got here. argv=%s\n", *argv);
|
||||||
|
goto usage;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inCc < 0)
|
||||||
|
perror (inFile);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
close (inFd);
|
||||||
|
close (outFd);
|
||||||
|
free (buf);
|
||||||
|
|
||||||
|
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:
|
||||||
|
|
||||||
|
fprintf (stderr, "%s", dd_usage);
|
||||||
|
exit( FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
47
dmesg.c
47
dmesg.c
@ -14,7 +14,6 @@
|
|||||||
|
|
||||||
#include <linux/unistd.h>
|
#include <linux/unistd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <getopt.h>
|
|
||||||
|
|
||||||
#define __NR_klog __NR_syslog
|
#define __NR_klog __NR_syslog
|
||||||
|
|
||||||
@ -25,56 +24,56 @@
|
|||||||
static inline _syscall3 (int, klog, int, type, char *, b, int, len)
|
static inline _syscall3 (int, klog, int, type, char *, b, int, len)
|
||||||
#endif /* __GLIBC__ */
|
#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];
|
char buf[4096];
|
||||||
int i;
|
int i;
|
||||||
int n;
|
int n;
|
||||||
int c;
|
|
||||||
int level = 0;
|
int level = 0;
|
||||||
int lastc;
|
int lastc;
|
||||||
int cmd = 3;
|
int cmd = 3;
|
||||||
|
|
||||||
while ((c = getopt( argc, argv, "cn:" )) != EOF) {
|
argc--;
|
||||||
switch (c) {
|
argv++;
|
||||||
|
|
||||||
|
/* Parse any options */
|
||||||
|
while (argc && **argv == '-') {
|
||||||
|
while (*++(*argv))
|
||||||
|
switch (**argv) {
|
||||||
case 'c':
|
case 'c':
|
||||||
cmd = 4;
|
cmd = 4;
|
||||||
break;
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
cmd = 8;
|
cmd = 8;
|
||||||
level = atoi(optarg);
|
if (--argc == 0)
|
||||||
|
goto end;
|
||||||
|
level = atoi (*(++argv));
|
||||||
|
--argc;
|
||||||
|
++argv;
|
||||||
break;
|
break;
|
||||||
case '?':
|
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "%s\n", dmesg_usage);
|
goto end;
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
argc -= optind;
|
|
||||||
argv += optind;
|
|
||||||
|
|
||||||
if (argc > 1) {
|
|
||||||
fprintf(stderr, "%s\n", dmesg_usage);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cmd == 8) {
|
if (cmd == 8) {
|
||||||
n = klog (cmd, NULL, level);
|
n = klog (cmd, NULL, level);
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
perror ("klog");
|
perror ("klog");
|
||||||
exit( 1 );
|
exit (FALSE);
|
||||||
}
|
}
|
||||||
exit( 0 );
|
exit (TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
n = klog (cmd, buf, sizeof (buf));
|
n = klog (cmd, buf, sizeof (buf));
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
perror ("klog");
|
perror ("klog");
|
||||||
exit( 1 );
|
exit (FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
lastc = '\n';
|
lastc = '\n';
|
||||||
@ -91,5 +90,9 @@ dmesg_main(int argc, char * * argv)
|
|||||||
}
|
}
|
||||||
if (lastc != '\n')
|
if (lastc != '\n')
|
||||||
putchar ('\n');
|
putchar ('\n');
|
||||||
return 0;
|
exit (TRUE);
|
||||||
|
|
||||||
|
end:
|
||||||
|
fprintf (stderr, "Usage: %s\n", dmesg_usage);
|
||||||
|
exit (FALSE);
|
||||||
}
|
}
|
||||||
|
35
dutmp.c
35
dutmp.c
@ -19,29 +19,34 @@ const char dutmp_usage[] = "dutmp\n"
|
|||||||
"\tDump file or stdin utmp file format to stdout, pipe delimited.\n"
|
"\tDump file or stdin utmp file format to stdout, pipe delimited.\n"
|
||||||
"\tdutmp /var/run/utmp\n";
|
"\tdutmp /var/run/utmp\n";
|
||||||
|
|
||||||
extern int
|
extern int dutmp_fn (int argc, char **argv)
|
||||||
dutmp_fn(const struct FileInfo * i)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
FILE *f = stdin;
|
FILE *f = stdin;
|
||||||
struct utmp * ut = (struct utmp *) malloc(sizeof(struct utmp) );
|
struct utmp ut;
|
||||||
|
|
||||||
if ( i )
|
if ((argc < 2) || (**(argv + 1) == '-')) {
|
||||||
if (! (f = fopen(i->source, "r"))) {
|
fprintf (stderr, "Usage: %s %s\n", *argv, dutmp_usage);
|
||||||
name_and_error(i->source);
|
exit (FALSE);
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (fread (ut, 1, sizeof(struct utmp), f)) {
|
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",
|
||||||
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_type, ut.ut_pid, ut.ut_line,
|
||||||
ut->ut_id, ut->ut_user, ut->ut_host,
|
ut.ut_id, ut.ut_user, ut.ut_host,
|
||||||
ut->ut_exit.e_termination, ut->ut_exit.e_exit,
|
ut.ut_exit.e_termination, ut.ut_exit.e_exit,
|
||||||
ut->ut_session,
|
ut.ut_session,
|
||||||
ut->ut_tv.tv_sec, ut->ut_tv.tv_usec,
|
ut.ut_tv.tv_sec, ut.ut_tv.tv_usec, ut.ut_addr);
|
||||||
ut->ut_addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
exit (TRUE);
|
||||||
}
|
}
|
||||||
|
146
findutils/grep.c
146
findutils/grep.c
@ -11,7 +11,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#ifdef BB_GREP
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <dirent.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)
|
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);
|
|
||||||
|
|
||||||
string++;
|
|
||||||
}
|
|
||||||
return (TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
/* END CODE */
|
/* END CODE */
|
||||||
|
|
||||||
|
|
||||||
|
146
grep.c
146
grep.c
@ -11,7 +11,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#ifdef BB_GREP
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <dirent.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)
|
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);
|
|
||||||
|
|
||||||
string++;
|
|
||||||
}
|
|
||||||
return (TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
/* END CODE */
|
/* END CODE */
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,12 +1,8 @@
|
|||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
const char reboot_usage[] = "reboot\n"
|
|
||||||
"\n\t"
|
|
||||||
"\treboot the system.\n";
|
|
||||||
|
|
||||||
extern int
|
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));
|
||||||
}
|
}
|
||||||
|
37
kill.c
37
kill.c
@ -88,20 +88,19 @@ const struct signal_name signames[] = {
|
|||||||
{0, 0}
|
{0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int
|
extern int kill_main (int argc, char **argv)
|
||||||
kill_main(struct FileInfo * i, int argc, char * * argv)
|
|
||||||
{
|
{
|
||||||
int had_error = 0;
|
int had_error = 0;
|
||||||
int sig = SIGTERM;
|
int sig = SIGTERM;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (argv[1][0] == '-') {
|
if (argv[1][0] == '-') {
|
||||||
if (argv[1][1] >= '0' && argv[1][1] <= '9') {
|
if (argv[1][1] >= '0' && argv[1][1] <= '9') {
|
||||||
sig = atoi (&argv[1][1]);
|
sig = atoi (&argv[1][1]);
|
||||||
if ( sig < 0 || sig >= NSIG ) {
|
if (sig < 0 || sig >= NSIG)
|
||||||
usage(kill_usage);
|
goto end;
|
||||||
exit(-1);
|
} else {
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const struct signal_name *s = signames;
|
const struct signal_name *s = signames;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (strcmp (s->name, &argv[1][1]) == 0) {
|
if (strcmp (s->name, &argv[1][1]) == 0) {
|
||||||
@ -109,10 +108,8 @@ kill_main(struct FileInfo * i, int argc, char * * argv)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
s++;
|
s++;
|
||||||
if ( s->name == 0 ) {
|
if (s->name == 0)
|
||||||
usage(kill_usage);
|
goto end;
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
argv++;
|
argv++;
|
||||||
@ -121,10 +118,8 @@ kill_main(struct FileInfo * i, int argc, char * * argv)
|
|||||||
}
|
}
|
||||||
while (argc > 1) {
|
while (argc > 1) {
|
||||||
int pid;
|
int pid;
|
||||||
if ( argv[1][0] < '0' || argv[1][0] > '9' ) {
|
if (argv[1][0] < '0' || argv[1][0] > '9')
|
||||||
usage(kill_usage);
|
goto end;
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
pid = atoi (argv[1]);
|
pid = atoi (argv[1]);
|
||||||
if (kill (pid, sig) != 0) {
|
if (kill (pid, sig) != 0) {
|
||||||
had_error = 1;
|
had_error = 1;
|
||||||
@ -133,8 +128,10 @@ kill_main(struct FileInfo * i, int argc, char * * argv)
|
|||||||
argv++;
|
argv++;
|
||||||
argc--;
|
argc--;
|
||||||
}
|
}
|
||||||
if ( had_error )
|
if (had_error) {
|
||||||
return -1;
|
end:
|
||||||
else
|
fprintf(stderr, "Usage: %s\n", kill_usage);
|
||||||
return 0;
|
exit ( FALSE);
|
||||||
|
}
|
||||||
|
exit (TRUE);
|
||||||
}
|
}
|
||||||
|
@ -19,29 +19,34 @@ const char dutmp_usage[] = "dutmp\n"
|
|||||||
"\tDump file or stdin utmp file format to stdout, pipe delimited.\n"
|
"\tDump file or stdin utmp file format to stdout, pipe delimited.\n"
|
||||||
"\tdutmp /var/run/utmp\n";
|
"\tdutmp /var/run/utmp\n";
|
||||||
|
|
||||||
extern int
|
extern int dutmp_fn (int argc, char **argv)
|
||||||
dutmp_fn(const struct FileInfo * i)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
FILE *f = stdin;
|
FILE *f = stdin;
|
||||||
struct utmp * ut = (struct utmp *) malloc(sizeof(struct utmp) );
|
struct utmp ut;
|
||||||
|
|
||||||
if ( i )
|
if ((argc < 2) || (**(argv + 1) == '-')) {
|
||||||
if (! (f = fopen(i->source, "r"))) {
|
fprintf (stderr, "Usage: %s %s\n", *argv, dutmp_usage);
|
||||||
name_and_error(i->source);
|
exit (FALSE);
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (fread (ut, 1, sizeof(struct utmp), f)) {
|
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",
|
||||||
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_type, ut.ut_pid, ut.ut_line,
|
||||||
ut->ut_id, ut->ut_user, ut->ut_host,
|
ut.ut_id, ut.ut_user, ut.ut_host,
|
||||||
ut->ut_exit.e_termination, ut->ut_exit.e_exit,
|
ut.ut_exit.e_termination, ut.ut_exit.e_exit,
|
||||||
ut->ut_session,
|
ut.ut_session,
|
||||||
ut->ut_tv.tv_sec, ut->ut_tv.tv_usec,
|
ut.ut_tv.tv_sec, ut.ut_tv.tv_usec, ut.ut_addr);
|
||||||
ut->ut_addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
exit (TRUE);
|
||||||
}
|
}
|
||||||
|
79
more.c
79
more.c
@ -19,27 +19,48 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Turning this off makes things a bit smaller (and less pretty) */
|
||||||
|
#define BB_MORE_TERM
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
|
|
||||||
const char more_usage[] = "[file ...]";
|
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)
|
extern int more_main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int c, lines=0;
|
int c, lines=0, input;
|
||||||
int next_page=0, rows = 24;
|
int next_page=0, rows = 24;
|
||||||
#ifdef ERASE_STUFF
|
#ifdef BB_MORE_TERM
|
||||||
int cols=79;
|
int cols;
|
||||||
|
struct winsize win;
|
||||||
#endif
|
#endif
|
||||||
struct stat st;
|
struct stat st;
|
||||||
FILE *file = stdin;
|
FILE *file = stdin;
|
||||||
|
|
||||||
if ( strcmp(*argv,"--help")==0 || strcmp(*argv,"-h")==0 ) {
|
if ( strcmp(*argv,"--help")==0 || strcmp(*argv,"-h")==0 ) {
|
||||||
fprintf(stderr, "Usage: %s %s", *argv, more_usage);
|
fprintf(stderr, "Usage: %s %s", *argv, more_usage);
|
||||||
return(FALSE);
|
exit(FALSE);
|
||||||
}
|
}
|
||||||
argc--;
|
argc--;
|
||||||
argv++;
|
argv++;
|
||||||
@ -48,23 +69,47 @@ extern int more_main(int argc, char **argv)
|
|||||||
file = fopen(*argv, "r");
|
file = fopen(*argv, "r");
|
||||||
if (file == NULL) {
|
if (file == NULL) {
|
||||||
perror("Can't open file");
|
perror("Can't open file");
|
||||||
return(FALSE);
|
exit(FALSE);
|
||||||
}
|
}
|
||||||
fstat(fileno(file), &st);
|
fstat(fileno(file), &st);
|
||||||
fprintf(stderr, "hi\n");
|
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) {
|
while ((c = getc(file)) != EOF) {
|
||||||
if ( next_page ) {
|
if ( next_page ) {
|
||||||
int len=0;
|
int len=0;
|
||||||
next_page = 0;
|
next_page = 0;
|
||||||
lines=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 )),
|
(int) (100*( (double) ftell(file) / (double) st.st_size )),
|
||||||
st.st_size);
|
st.st_size,
|
||||||
|
#ifdef BB_MORE_TERM
|
||||||
|
""
|
||||||
|
#else
|
||||||
|
"\n"
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
getc( stdin);
|
input = getc( stdin);
|
||||||
#ifdef ERASE_STUFF
|
|
||||||
/* Try to erase the "More" message */
|
#ifdef BB_MORE_TERM
|
||||||
|
/* Erase the "More" message */
|
||||||
while(len-- > 0)
|
while(len-- > 0)
|
||||||
putc('\b', stdout);
|
putc('\b', stdout);
|
||||||
while(len++ < cols)
|
while(len++ < cols)
|
||||||
@ -73,7 +118,12 @@ extern int more_main(int argc, char **argv)
|
|||||||
putc('\b', stdout);
|
putc('\b', stdout);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
if (input=='q')
|
||||||
|
goto end;
|
||||||
|
if (input==' ' && c == '\n' )
|
||||||
|
next_page = 1;
|
||||||
if ( c == '\n' && ++lines == (rows + 1) )
|
if ( c == '\n' && ++lines == (rows + 1) )
|
||||||
next_page = 1;
|
next_page = 1;
|
||||||
putc(c, stdout);
|
putc(c, stdout);
|
||||||
@ -84,7 +134,10 @@ extern int more_main(int argc, char **argv)
|
|||||||
argc--;
|
argc--;
|
||||||
argv++;
|
argv++;
|
||||||
}
|
}
|
||||||
return(TRUE);
|
end:
|
||||||
|
#ifdef BB_MORE_TERM
|
||||||
|
gotsig(0);
|
||||||
|
#endif
|
||||||
|
exit(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -88,20 +88,19 @@ const struct signal_name signames[] = {
|
|||||||
{0, 0}
|
{0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int
|
extern int kill_main (int argc, char **argv)
|
||||||
kill_main(struct FileInfo * i, int argc, char * * argv)
|
|
||||||
{
|
{
|
||||||
int had_error = 0;
|
int had_error = 0;
|
||||||
int sig = SIGTERM;
|
int sig = SIGTERM;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (argv[1][0] == '-') {
|
if (argv[1][0] == '-') {
|
||||||
if (argv[1][1] >= '0' && argv[1][1] <= '9') {
|
if (argv[1][1] >= '0' && argv[1][1] <= '9') {
|
||||||
sig = atoi (&argv[1][1]);
|
sig = atoi (&argv[1][1]);
|
||||||
if ( sig < 0 || sig >= NSIG ) {
|
if (sig < 0 || sig >= NSIG)
|
||||||
usage(kill_usage);
|
goto end;
|
||||||
exit(-1);
|
} else {
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const struct signal_name *s = signames;
|
const struct signal_name *s = signames;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (strcmp (s->name, &argv[1][1]) == 0) {
|
if (strcmp (s->name, &argv[1][1]) == 0) {
|
||||||
@ -109,10 +108,8 @@ kill_main(struct FileInfo * i, int argc, char * * argv)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
s++;
|
s++;
|
||||||
if ( s->name == 0 ) {
|
if (s->name == 0)
|
||||||
usage(kill_usage);
|
goto end;
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
argv++;
|
argv++;
|
||||||
@ -121,10 +118,8 @@ kill_main(struct FileInfo * i, int argc, char * * argv)
|
|||||||
}
|
}
|
||||||
while (argc > 1) {
|
while (argc > 1) {
|
||||||
int pid;
|
int pid;
|
||||||
if ( argv[1][0] < '0' || argv[1][0] > '9' ) {
|
if (argv[1][0] < '0' || argv[1][0] > '9')
|
||||||
usage(kill_usage);
|
goto end;
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
pid = atoi (argv[1]);
|
pid = atoi (argv[1]);
|
||||||
if (kill (pid, sig) != 0) {
|
if (kill (pid, sig) != 0) {
|
||||||
had_error = 1;
|
had_error = 1;
|
||||||
@ -133,8 +128,10 @@ kill_main(struct FileInfo * i, int argc, char * * argv)
|
|||||||
argv++;
|
argv++;
|
||||||
argc--;
|
argc--;
|
||||||
}
|
}
|
||||||
if ( had_error )
|
if (had_error) {
|
||||||
return -1;
|
end:
|
||||||
else
|
fprintf(stderr, "Usage: %s\n", kill_usage);
|
||||||
return 0;
|
exit ( FALSE);
|
||||||
|
}
|
||||||
|
exit (TRUE);
|
||||||
}
|
}
|
||||||
|
3
pwd.c
3
pwd.c
@ -1,12 +1,13 @@
|
|||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
|
||||||
const char pwd_usage[] = "Print the current directory.\n";
|
const char pwd_usage[] = "Print the current directory.\n";
|
||||||
|
|
||||||
extern int
|
extern int
|
||||||
pwd_main(int argc, char * * argv)
|
pwd_main(int argc, char * * argv)
|
||||||
{
|
{
|
||||||
char buf[1024];
|
char buf[NAME_MAX];
|
||||||
|
|
||||||
if ( getcwd(buf, sizeof(buf)) == NULL ) {
|
if ( getcwd(buf, sizeof(buf)) == NULL ) {
|
||||||
perror("get working directory");
|
perror("get working directory");
|
||||||
|
8
reboot.c
8
reboot.c
@ -1,12 +1,8 @@
|
|||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
const char reboot_usage[] = "reboot\n"
|
|
||||||
"\n\t"
|
|
||||||
"\treboot the system.\n";
|
|
||||||
|
|
||||||
extern int
|
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));
|
||||||
}
|
}
|
||||||
|
21
sleep.c
21
sleep.c
@ -1,15 +1,20 @@
|
|||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
const char sleep_usage[] = "sleep seconds\n"
|
const char sleep_usage[] = " NUMBER\n"
|
||||||
"\n"
|
"Pause for NUMBER seconds.\n";
|
||||||
"\tPause program execution for the given number of seconds.\n";
|
|
||||||
|
|
||||||
extern int
|
extern int
|
||||||
sleep_main(struct FileInfo * i, int argc, char * * argv)
|
sleep_main(int argc, char * * argv)
|
||||||
{
|
{
|
||||||
if ( sleep(atoi(argv[1])) != 0 )
|
if ( (argc < 2) || (**(argv+1) == '-') ) {
|
||||||
return -1;
|
fprintf(stderr, "Usage: %s %s", *argv, sleep_usage);
|
||||||
else
|
exit(FALSE);
|
||||||
return 0;
|
}
|
||||||
|
|
||||||
|
if ( sleep(atoi(*(++argv))) != 0 ) {
|
||||||
|
perror( "sleep");
|
||||||
|
exit (FALSE);
|
||||||
|
} else
|
||||||
|
exit (TRUE);
|
||||||
}
|
}
|
||||||
|
234
tar.c
234
tar.c
@ -7,7 +7,7 @@
|
|||||||
* This allows creation, extraction, and listing of tar files.
|
* This allows creation, extraction, and listing of tar files.
|
||||||
*
|
*
|
||||||
* Permission to distribute this code under the GPL has been granted.
|
* Permission to distribute this code under the GPL has been granted.
|
||||||
* Modified for busybox by Erik Andersen <andersee@debian.org> <andersen@lineo.com>
|
* Modified for busybox by Erik Andersen <andersee@debian.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@ -42,8 +42,7 @@ const char tar_usage[] =
|
|||||||
* This structure is always embedded in a TAR_BLOCK_SIZE sized block
|
* This structure is always embedded in a TAR_BLOCK_SIZE sized block
|
||||||
* with zero padding. We only process this information minimally.
|
* with zero padding. We only process this information minimally.
|
||||||
*/
|
*/
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
char name[TAR_NAME_SIZE];
|
char name[TAR_NAME_SIZE];
|
||||||
char mode[8];
|
char mode[8];
|
||||||
char uid[8];
|
char uid[8];
|
||||||
@ -125,26 +124,23 @@ static void saveDirectory(const char * fileName,
|
|||||||
static int wantFileName (const char *fileName,
|
static int wantFileName (const char *fileName,
|
||||||
int fileCount, char **fileTable);
|
int fileCount, char **fileTable);
|
||||||
|
|
||||||
static void writeHeader(const char * fileName,
|
static void writeHeader (const char *fileName, const struct stat *statbuf);
|
||||||
const struct stat * statbuf);
|
|
||||||
|
|
||||||
static void writeTarFile (int fileCount, char **fileTable);
|
static void writeTarFile (int fileCount, char **fileTable);
|
||||||
static void writeTarBlock (const char *buf, int len);
|
static void writeTarBlock (const char *buf, int len);
|
||||||
static int putOctal (char *cp, int len, long value);
|
static int putOctal (char *cp, int len, long value);
|
||||||
|
|
||||||
|
|
||||||
extern int
|
extern int tar_main (int argc, char **argv)
|
||||||
tar_main(int argc, char ** argv)
|
|
||||||
{
|
{
|
||||||
const char *options;
|
const char *options;
|
||||||
|
|
||||||
argc--;
|
argc--;
|
||||||
argv++;
|
argv++;
|
||||||
|
|
||||||
if (argc < 1)
|
if (argc < 1) {
|
||||||
{
|
|
||||||
fprintf (stderr, "%s", tar_usage);
|
fprintf (stderr, "%s", tar_usage);
|
||||||
return 1;
|
exit (FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -166,16 +162,13 @@ tar_main(int argc, char ** argv)
|
|||||||
argc--;
|
argc--;
|
||||||
|
|
||||||
if (**argv == '-') {
|
if (**argv == '-') {
|
||||||
for (; *options; options++)
|
for (; *options; options++) {
|
||||||
{
|
switch (*options) {
|
||||||
switch (*options)
|
|
||||||
{
|
|
||||||
case 'f':
|
case 'f':
|
||||||
if (tarName != NULL)
|
if (tarName != NULL) {
|
||||||
{
|
|
||||||
fprintf (stderr, "Only one 'f' option allowed\n");
|
fprintf (stderr, "Only one 'f' option allowed\n");
|
||||||
|
|
||||||
return 1;
|
exit (FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
tarName = *argv++;
|
tarName = *argv++;
|
||||||
@ -209,7 +202,7 @@ tar_main(int argc, char ** argv)
|
|||||||
default:
|
default:
|
||||||
fprintf (stderr, "Unknown tar flag '%c'\n", *options);
|
fprintf (stderr, "Unknown tar flag '%c'\n", *options);
|
||||||
|
|
||||||
return 1;
|
exit (FALSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -217,11 +210,11 @@ tar_main(int argc, char ** argv)
|
|||||||
/*
|
/*
|
||||||
* Validate the options.
|
* Validate the options.
|
||||||
*/
|
*/
|
||||||
if (extractFlag + listFlag + createFlag != 1)
|
if (extractFlag + listFlag + createFlag != 1) {
|
||||||
{
|
fprintf (stderr,
|
||||||
fprintf(stderr, "Exactly one of 'c', 'x' or 't' must be specified\n");
|
"Exactly one of 'c', 'x' or 't' must be specified\n");
|
||||||
|
|
||||||
return 1;
|
exit (FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -234,7 +227,7 @@ tar_main(int argc, char ** argv)
|
|||||||
readTarFile (argc, argv);
|
readTarFile (argc, argv);
|
||||||
if (errorFlag)
|
if (errorFlag)
|
||||||
fprintf (stderr, "\n");
|
fprintf (stderr, "\n");
|
||||||
return( errorFlag);
|
exit (errorFlag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -242,8 +235,7 @@ tar_main(int argc, char ** argv)
|
|||||||
* Read a tar file and extract or list the specified files within it.
|
* 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.
|
* If the list is empty than all files are extracted or listed.
|
||||||
*/
|
*/
|
||||||
static void
|
static void readTarFile (int fileCount, char **fileTable)
|
||||||
readTarFile(int fileCount, char ** fileTable)
|
|
||||||
{
|
{
|
||||||
const char *cp;
|
const char *cp;
|
||||||
int cc;
|
int cc;
|
||||||
@ -267,12 +259,10 @@ readTarFile(int fileCount, char ** fileTable)
|
|||||||
*/
|
*/
|
||||||
if ((tarName == NULL) || !strcmp (tarName, "-")) {
|
if ((tarName == NULL) || !strcmp (tarName, "-")) {
|
||||||
tarFd = STDIN;
|
tarFd = STDIN;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
tarFd = open (tarName, O_RDONLY);
|
tarFd = open (tarName, O_RDONLY);
|
||||||
|
|
||||||
if (tarFd < 0)
|
if (tarFd < 0) {
|
||||||
{
|
|
||||||
perror (tarName);
|
perror (tarName);
|
||||||
errorFlag = TRUE;
|
errorFlag = TRUE;
|
||||||
return;
|
return;
|
||||||
@ -282,30 +272,25 @@ readTarFile(int fileCount, char ** fileTable)
|
|||||||
* Read blocks from the file until an end of file header block
|
* 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.)
|
* has been seen. (A real end of file from a read is an error.)
|
||||||
*/
|
*/
|
||||||
while (!eofFlag)
|
while (!eofFlag) {
|
||||||
{
|
|
||||||
/*
|
/*
|
||||||
* Read the next block of data if necessary.
|
* Read the next block of data if necessary.
|
||||||
* This will be a large block if possible, which we will
|
* This will be a large block if possible, which we will
|
||||||
* then process in the small tar blocks.
|
* then process in the small tar blocks.
|
||||||
*/
|
*/
|
||||||
if (inCc <= 0)
|
if (inCc <= 0) {
|
||||||
{
|
|
||||||
cp = buf;
|
cp = buf;
|
||||||
inCc = fullRead (tarFd, buf, blockSize);
|
inCc = fullRead (tarFd, buf, blockSize);
|
||||||
|
|
||||||
if (inCc < 0)
|
if (inCc < 0) {
|
||||||
{
|
|
||||||
perror (tarName);
|
perror (tarName);
|
||||||
errorFlag = TRUE;
|
errorFlag = TRUE;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inCc == 0)
|
if (inCc == 0) {
|
||||||
{
|
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
"Unexpected end of file from \"%s\"",
|
"Unexpected end of file from \"%s\"", tarName);
|
||||||
tarName);
|
|
||||||
errorFlag = TRUE;
|
errorFlag = TRUE;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
@ -314,8 +299,7 @@ readTarFile(int fileCount, char ** fileTable)
|
|||||||
/*
|
/*
|
||||||
* If we are expecting a header block then examine it.
|
* If we are expecting a header block then examine it.
|
||||||
*/
|
*/
|
||||||
if (inHeader)
|
if (inHeader) {
|
||||||
{
|
|
||||||
readHeader ((const TarHeader *) cp, fileCount, fileTable);
|
readHeader ((const TarHeader *) cp, fileCount, fileTable);
|
||||||
|
|
||||||
cp += TAR_BLOCK_SIZE;
|
cp += TAR_BLOCK_SIZE;
|
||||||
@ -392,10 +376,8 @@ readHeader(const TarHeader * hp, int fileCount, char ** fileTable)
|
|||||||
*/
|
*/
|
||||||
name = hp->name;
|
name = hp->name;
|
||||||
|
|
||||||
if (*name == '\0')
|
if (*name == '\0') {
|
||||||
{
|
for (cc = TAR_BLOCK_SIZE; cc > 0; cc--) {
|
||||||
for (cc = TAR_BLOCK_SIZE; cc > 0; cc--)
|
|
||||||
{
|
|
||||||
if (*name++)
|
if (*name++)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -416,8 +398,7 @@ readHeader(const TarHeader * hp, int fileCount, char ** fileTable)
|
|||||||
mtime = getOctal (hp->mtime, sizeof (hp->mtime));
|
mtime = getOctal (hp->mtime, sizeof (hp->mtime));
|
||||||
checkSum = getOctal (hp->checkSum, sizeof (hp->checkSum));
|
checkSum = getOctal (hp->checkSum, sizeof (hp->checkSum));
|
||||||
|
|
||||||
if ((mode < 0) || (uid < 0) || (gid < 0) || (size < 0))
|
if ((mode < 0) || (uid < 0) || (gid < 0) || (size < 0)) {
|
||||||
{
|
|
||||||
if (!badHeader)
|
if (!badHeader)
|
||||||
fprintf (stderr, "Bad tar header, skipping\n");
|
fprintf (stderr, "Bad tar header, skipping\n");
|
||||||
|
|
||||||
@ -450,13 +431,11 @@ readHeader(const TarHeader * hp, int fileCount, char ** fileTable)
|
|||||||
* Check for absolute paths in the file.
|
* Check for absolute paths in the file.
|
||||||
* If we find any, then warn the user and make them relative.
|
* If we find any, then warn the user and make them relative.
|
||||||
*/
|
*/
|
||||||
if (*name == '/')
|
if (*name == '/') {
|
||||||
{
|
|
||||||
while (*name == '/')
|
while (*name == '/')
|
||||||
name++;
|
name++;
|
||||||
|
|
||||||
if (!warnedRoot)
|
if (!warnedRoot) {
|
||||||
{
|
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
"Absolute path detected, removing leading slashes\n");
|
"Absolute path detected, removing leading slashes\n");
|
||||||
}
|
}
|
||||||
@ -468,10 +447,8 @@ readHeader(const TarHeader * hp, int fileCount, char ** fileTable)
|
|||||||
* See if we want this file to be restored.
|
* See if we want this file to be restored.
|
||||||
* If not, then set up to skip it.
|
* If not, then set up to skip it.
|
||||||
*/
|
*/
|
||||||
if (!wantFileName(name, fileCount, fileTable))
|
if (!wantFileName (name, fileCount, fileTable)) {
|
||||||
{
|
if (!hardLink && !softLink && S_ISREG (mode)) {
|
||||||
if (!hardLink && !softLink && S_ISREG(mode))
|
|
||||||
{
|
|
||||||
inHeader = (size == 0);
|
inHeader = (size == 0);
|
||||||
dataCc = size;
|
dataCc = size;
|
||||||
}
|
}
|
||||||
@ -485,22 +462,18 @@ readHeader(const TarHeader * hp, int fileCount, char ** fileTable)
|
|||||||
* This file is to be handled.
|
* This file is to be handled.
|
||||||
* If we aren't extracting then just list information about the file.
|
* If we aren't extracting then just list information about the file.
|
||||||
*/
|
*/
|
||||||
if (!extractFlag)
|
if (!extractFlag) {
|
||||||
{
|
if (verboseFlag) {
|
||||||
if (verboseFlag)
|
|
||||||
{
|
|
||||||
printf ("%s %3d/%-d %9ld %s %s", modeString (mode),
|
printf ("%s %3d/%-d %9ld %s %s", modeString (mode),
|
||||||
uid, gid, size, timeString (mtime), name);
|
uid, gid, size, timeString (mtime), name);
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
printf ("%s", name);
|
printf ("%s", name);
|
||||||
|
|
||||||
if (hardLink)
|
if (hardLink)
|
||||||
printf (" (link to \"%s\")", hp->linkName);
|
printf (" (link to \"%s\")", hp->linkName);
|
||||||
else if (softLink)
|
else if (softLink)
|
||||||
printf (" (symlink to \"%s\")", hp->linkName);
|
printf (" (symlink to \"%s\")", hp->linkName);
|
||||||
else if (S_ISREG(mode))
|
else if (S_ISREG (mode)) {
|
||||||
{
|
|
||||||
inHeader = (size == 0);
|
inHeader = (size == 0);
|
||||||
dataCc = size;
|
dataCc = size;
|
||||||
}
|
}
|
||||||
@ -516,16 +489,14 @@ readHeader(const TarHeader * hp, int fileCount, char ** fileTable)
|
|||||||
if (verboseFlag)
|
if (verboseFlag)
|
||||||
printf ("x %s\n", name);
|
printf ("x %s\n", name);
|
||||||
|
|
||||||
if (hardLink)
|
if (hardLink) {
|
||||||
{
|
|
||||||
if (link (hp->linkName, name) < 0)
|
if (link (hp->linkName, name) < 0)
|
||||||
perror (name);
|
perror (name);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (softLink)
|
if (softLink) {
|
||||||
{
|
|
||||||
#ifdef S_ISLNK
|
#ifdef S_ISLNK
|
||||||
if (symlink (hp->linkName, name) < 0)
|
if (symlink (hp->linkName, name) < 0)
|
||||||
perror (name);
|
perror (name);
|
||||||
@ -538,8 +509,7 @@ readHeader(const TarHeader * hp, int fileCount, char ** fileTable)
|
|||||||
/*
|
/*
|
||||||
* If the file is a directory, then just create the path.
|
* If the file is a directory, then just create the path.
|
||||||
*/
|
*/
|
||||||
if (S_ISDIR(mode))
|
if (S_ISDIR (mode)) {
|
||||||
{
|
|
||||||
createPath (name, mode);
|
createPath (name, mode);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -562,8 +532,7 @@ readHeader(const TarHeader * hp, int fileCount, char ** fileTable)
|
|||||||
else
|
else
|
||||||
outFd = open (name, O_WRONLY | O_CREAT | O_TRUNC, mode);
|
outFd = open (name, O_WRONLY | O_CREAT | O_TRUNC, mode);
|
||||||
|
|
||||||
if (outFd < 0)
|
if (outFd < 0) {
|
||||||
{
|
|
||||||
perror (name);
|
perror (name);
|
||||||
skipFileFlag = TRUE;
|
skipFileFlag = TRUE;
|
||||||
return;
|
return;
|
||||||
@ -572,8 +541,7 @@ readHeader(const TarHeader * hp, int fileCount, char ** fileTable)
|
|||||||
/*
|
/*
|
||||||
* If the file is empty, then that's all we need to do.
|
* If the file is empty, then that's all we need to do.
|
||||||
*/
|
*/
|
||||||
if (size == 0 && tostdoutFlag == FALSE)
|
if (size == 0 && tostdoutFlag == FALSE) {
|
||||||
{
|
|
||||||
(void) close (outFd);
|
(void) close (outFd);
|
||||||
outFd = -1;
|
outFd = -1;
|
||||||
}
|
}
|
||||||
@ -583,8 +551,7 @@ readHeader(const TarHeader * hp, int fileCount, char ** fileTable)
|
|||||||
/*
|
/*
|
||||||
* Handle a data block of some specified size that was read.
|
* Handle a data block of some specified size that was read.
|
||||||
*/
|
*/
|
||||||
static void
|
static void readData (const char *cp, int count)
|
||||||
readData(const char * cp, int count)
|
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Reduce the amount of data left in this file.
|
* Reduce the amount of data left in this file.
|
||||||
@ -606,8 +573,7 @@ readData(const char * cp, int count)
|
|||||||
/*
|
/*
|
||||||
* Write the data to the output file.
|
* Write the data to the output file.
|
||||||
*/
|
*/
|
||||||
if (fullWrite(outFd, cp, count) < 0)
|
if (fullWrite (outFd, cp, count) < 0) {
|
||||||
{
|
|
||||||
perror (outName);
|
perror (outName);
|
||||||
if (tostdoutFlag == FALSE) {
|
if (tostdoutFlag == FALSE) {
|
||||||
(void) close (outFd);
|
(void) close (outFd);
|
||||||
@ -621,8 +587,7 @@ readData(const char * cp, int count)
|
|||||||
* If the write failed, close the file and disable further
|
* If the write failed, close the file and disable further
|
||||||
* writes to this file.
|
* writes to this file.
|
||||||
*/
|
*/
|
||||||
if (dataCc <= 0 && tostdoutFlag==FALSE)
|
if (dataCc <= 0 && tostdoutFlag == FALSE) {
|
||||||
{
|
|
||||||
if (close (outFd))
|
if (close (outFd))
|
||||||
perror (outName);
|
perror (outName);
|
||||||
|
|
||||||
@ -634,16 +599,14 @@ readData(const char * cp, int count)
|
|||||||
/*
|
/*
|
||||||
* Write a tar file containing the specified files.
|
* Write a tar file containing the specified files.
|
||||||
*/
|
*/
|
||||||
static void
|
static void writeTarFile (int fileCount, char **fileTable)
|
||||||
writeTarFile(int fileCount, char ** fileTable)
|
|
||||||
{
|
{
|
||||||
struct stat statbuf;
|
struct stat statbuf;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make sure there is at least one file specified.
|
* Make sure there is at least one file specified.
|
||||||
*/
|
*/
|
||||||
if (fileCount <= 0)
|
if (fileCount <= 0) {
|
||||||
{
|
|
||||||
fprintf (stderr, "No files specified to be saved\n");
|
fprintf (stderr, "No files specified to be saved\n");
|
||||||
errorFlag = TRUE;
|
errorFlag = TRUE;
|
||||||
}
|
}
|
||||||
@ -654,12 +617,10 @@ writeTarFile(int fileCount, char ** fileTable)
|
|||||||
if ((tarName == NULL) || !strcmp (tarName, "-")) {
|
if ((tarName == NULL) || !strcmp (tarName, "-")) {
|
||||||
tostdoutFlag = TRUE;
|
tostdoutFlag = TRUE;
|
||||||
tarFd = STDOUT;
|
tarFd = STDOUT;
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
tarFd = open (tarName, O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
tarFd = open (tarName, O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
||||||
|
|
||||||
if (tarFd < 0)
|
if (tarFd < 0) {
|
||||||
{
|
|
||||||
perror (tarName);
|
perror (tarName);
|
||||||
errorFlag = TRUE;
|
errorFlag = TRUE;
|
||||||
return;
|
return;
|
||||||
@ -668,8 +629,7 @@ writeTarFile(int fileCount, char ** fileTable)
|
|||||||
/*
|
/*
|
||||||
* Get the device and inode of the tar file for checking later.
|
* Get the device and inode of the tar file for checking later.
|
||||||
*/
|
*/
|
||||||
if (fstat(tarFd, &statbuf) < 0)
|
if (fstat (tarFd, &statbuf) < 0) {
|
||||||
{
|
|
||||||
perror (tarName);
|
perror (tarName);
|
||||||
errorFlag = TRUE;
|
errorFlag = TRUE;
|
||||||
goto done;
|
goto done;
|
||||||
@ -682,8 +642,7 @@ writeTarFile(int fileCount, char ** fileTable)
|
|||||||
* Append each file name into the archive file.
|
* Append each file name into the archive file.
|
||||||
* Follow symbolic links for these top level file names.
|
* Follow symbolic links for these top level file names.
|
||||||
*/
|
*/
|
||||||
while (!errorFlag && (fileCount-- > 0))
|
while (!errorFlag && (fileCount-- > 0)) {
|
||||||
{
|
|
||||||
saveFile (*fileTable++, FALSE);
|
saveFile (*fileTable++, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -709,8 +668,7 @@ done:
|
|||||||
* flag indicates whether or not we want to see symbolic links as
|
* flag indicates whether or not we want to see symbolic links as
|
||||||
* they really are, instead of blindly following them.
|
* they really are, instead of blindly following them.
|
||||||
*/
|
*/
|
||||||
static void
|
static void saveFile (const char *fileName, int seeLinks)
|
||||||
saveFile(const char * fileName, int seeLinks)
|
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
int mode;
|
int mode;
|
||||||
@ -722,8 +680,7 @@ saveFile(const char * fileName, int seeLinks)
|
|||||||
/*
|
/*
|
||||||
* Check that the file name will fit in the header.
|
* Check that the file name will fit in the header.
|
||||||
*/
|
*/
|
||||||
if (strlen(fileName) >= TAR_NAME_SIZE)
|
if (strlen (fileName) >= TAR_NAME_SIZE) {
|
||||||
{
|
|
||||||
fprintf (stderr, "%s: File name is too long\n", fileName);
|
fprintf (stderr, "%s: File name is too long\n", fileName);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -739,8 +696,7 @@ saveFile(const char * fileName, int seeLinks)
|
|||||||
#endif
|
#endif
|
||||||
status = stat (fileName, &statbuf);
|
status = stat (fileName, &statbuf);
|
||||||
|
|
||||||
if (status < 0)
|
if (status < 0) {
|
||||||
{
|
|
||||||
perror (fileName);
|
perror (fileName);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -749,8 +705,7 @@ saveFile(const char * fileName, int seeLinks)
|
|||||||
/*
|
/*
|
||||||
* Make sure we aren't trying to save our file into itself.
|
* Make sure we aren't trying to save our file into itself.
|
||||||
*/
|
*/
|
||||||
if ((statbuf.st_dev == tarDev) && (statbuf.st_ino == tarInode))
|
if ((statbuf.st_dev == tarDev) && (statbuf.st_ino == tarInode)) {
|
||||||
{
|
|
||||||
fprintf (stderr, "Skipping saving of archive file itself\n");
|
fprintf (stderr, "Skipping saving of archive file itself\n");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -761,15 +716,13 @@ saveFile(const char * fileName, int seeLinks)
|
|||||||
*/
|
*/
|
||||||
mode = statbuf.st_mode;
|
mode = statbuf.st_mode;
|
||||||
|
|
||||||
if (S_ISDIR(mode))
|
if (S_ISDIR (mode)) {
|
||||||
{
|
|
||||||
saveDirectory (fileName, &statbuf);
|
saveDirectory (fileName, &statbuf);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (S_ISREG(mode))
|
if (S_ISREG (mode)) {
|
||||||
{
|
|
||||||
saveRegularFile (fileName, &statbuf);
|
saveRegularFile (fileName, &statbuf);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -800,8 +753,7 @@ saveRegularFile(const char * fileName, const struct stat * statbuf)
|
|||||||
*/
|
*/
|
||||||
fileFd = open (fileName, O_RDONLY);
|
fileFd = open (fileName, O_RDONLY);
|
||||||
|
|
||||||
if (fileFd < 0)
|
if (fileFd < 0) {
|
||||||
{
|
|
||||||
perror (fileName);
|
perror (fileName);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -821,8 +773,7 @@ saveRegularFile(const char * fileName, const struct stat * statbuf)
|
|||||||
fullDataCount = statbuf->st_size;
|
fullDataCount = statbuf->st_size;
|
||||||
sawEof = FALSE;
|
sawEof = FALSE;
|
||||||
|
|
||||||
while (fullDataCount > 0)
|
while (fullDataCount > 0) {
|
||||||
{
|
|
||||||
/*
|
/*
|
||||||
* Get the amount to write this iteration which is
|
* Get the amount to write this iteration which is
|
||||||
* the minumum of the amount left to write and the
|
* the minumum of the amount left to write and the
|
||||||
@ -839,12 +790,10 @@ saveRegularFile(const char * fileName, const struct stat * statbuf)
|
|||||||
*/
|
*/
|
||||||
cc = 0;
|
cc = 0;
|
||||||
|
|
||||||
if (!sawEof)
|
if (!sawEof) {
|
||||||
{
|
|
||||||
cc = fullRead (fileFd, data, dataCount);
|
cc = fullRead (fileFd, data, dataCount);
|
||||||
|
|
||||||
if (cc < 0)
|
if (cc < 0) {
|
||||||
{
|
|
||||||
perror (fileName);
|
perror (fileName);
|
||||||
|
|
||||||
(void) close (fileFd);
|
(void) close (fileFd);
|
||||||
@ -857,11 +806,9 @@ saveRegularFile(const char * fileName, const struct stat * statbuf)
|
|||||||
* If the file ended too soon, complain and set
|
* If the file ended too soon, complain and set
|
||||||
* a flag so we will zero fill the rest of it.
|
* a flag so we will zero fill the rest of it.
|
||||||
*/
|
*/
|
||||||
if (cc < dataCount)
|
if (cc < dataCount) {
|
||||||
{
|
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
"%s: Short read - zero filling",
|
"%s: Short read - zero filling", fileName);
|
||||||
fileName);
|
|
||||||
|
|
||||||
sawEof = TRUE;
|
sawEof = TRUE;
|
||||||
}
|
}
|
||||||
@ -892,8 +839,7 @@ saveRegularFile(const char * fileName, const struct stat * statbuf)
|
|||||||
/*
|
/*
|
||||||
* Save a directory and all of its files to the tar file.
|
* Save a directory and all of its files to the tar file.
|
||||||
*/
|
*/
|
||||||
static void
|
static void saveDirectory (const char *dirName, const struct stat *statbuf)
|
||||||
saveDirectory(const char * dirName, const struct stat * statbuf)
|
|
||||||
{
|
{
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
struct dirent *entry;
|
struct dirent *entry;
|
||||||
@ -917,8 +863,7 @@ saveDirectory(const char * dirName, const struct stat * statbuf)
|
|||||||
*/
|
*/
|
||||||
dir = opendir (dirName);
|
dir = opendir (dirName);
|
||||||
|
|
||||||
if (dir == NULL)
|
if (dir == NULL) {
|
||||||
{
|
|
||||||
fprintf (stderr, "Cannot read directory \"%s\": %s\n",
|
fprintf (stderr, "Cannot read directory \"%s\": %s\n",
|
||||||
dirName, strerror (errno));
|
dirName, strerror (errno));
|
||||||
|
|
||||||
@ -934,11 +879,9 @@ saveDirectory(const char * dirName, const struct stat * statbuf)
|
|||||||
* Read all of the directory entries and check them,
|
* Read all of the directory entries and check them,
|
||||||
* except for the current and parent directory entries.
|
* except for the current and parent directory entries.
|
||||||
*/
|
*/
|
||||||
while (!errorFlag && ((entry = readdir(dir)) != NULL))
|
while (!errorFlag && ((entry = readdir (dir)) != NULL)) {
|
||||||
{
|
|
||||||
if ((strcmp (entry->d_name, ".") == 0) ||
|
if ((strcmp (entry->d_name, ".") == 0) ||
|
||||||
(strcmp(entry->d_name, "..") == 0))
|
(strcmp (entry->d_name, "..") == 0)) {
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -970,8 +913,7 @@ saveDirectory(const char * dirName, const struct stat * statbuf)
|
|||||||
* Write a tar header for the specified file name and status.
|
* Write a tar header for the specified file name and status.
|
||||||
* It is assumed that the file name fits.
|
* It is assumed that the file name fits.
|
||||||
*/
|
*/
|
||||||
static void
|
static void writeHeader (const char *fileName, const struct stat *statbuf)
|
||||||
writeHeader(const char * fileName, const struct stat * statbuf)
|
|
||||||
{
|
{
|
||||||
long checkSum;
|
long checkSum;
|
||||||
const unsigned char *cp;
|
const unsigned char *cp;
|
||||||
@ -1027,8 +969,7 @@ writeHeader(const char * fileName, const struct stat * statbuf)
|
|||||||
* The data is always padded out to a multiple of TAR_BLOCK_SIZE.
|
* The data is always padded out to a multiple of TAR_BLOCK_SIZE.
|
||||||
* The errorFlag static variable is set on an error.
|
* The errorFlag static variable is set on an error.
|
||||||
*/
|
*/
|
||||||
static void
|
static void writeTarBlock (const char *buf, int len)
|
||||||
writeTarBlock(const char * buf, int len)
|
|
||||||
{
|
{
|
||||||
int partialLength;
|
int partialLength;
|
||||||
int completeLength;
|
int completeLength;
|
||||||
@ -1049,8 +990,7 @@ writeTarBlock(const char * buf, int len)
|
|||||||
/*
|
/*
|
||||||
* Write all of the complete blocks.
|
* Write all of the complete blocks.
|
||||||
*/
|
*/
|
||||||
if ((completeLength > 0) && !fullWrite(tarFd, buf, completeLength))
|
if ((completeLength > 0) && !fullWrite (tarFd, buf, completeLength)) {
|
||||||
{
|
|
||||||
perror (tarName);
|
perror (tarName);
|
||||||
|
|
||||||
errorFlag = TRUE;
|
errorFlag = TRUE;
|
||||||
@ -1074,8 +1014,7 @@ writeTarBlock(const char * buf, int len)
|
|||||||
/*
|
/*
|
||||||
* Write the last complete block.
|
* Write the last complete block.
|
||||||
*/
|
*/
|
||||||
if (!fullWrite(tarFd, fullBlock, TAR_BLOCK_SIZE))
|
if (!fullWrite (tarFd, fullBlock, TAR_BLOCK_SIZE)) {
|
||||||
{
|
|
||||||
perror (tarName);
|
perror (tarName);
|
||||||
|
|
||||||
errorFlag = TRUE;
|
errorFlag = TRUE;
|
||||||
@ -1089,8 +1028,7 @@ writeTarBlock(const char * buf, int len)
|
|||||||
* while all previous ones get default protections. Errors are not reported
|
* while all previous ones get default protections. Errors are not reported
|
||||||
* here, as failures to restore files can be reported later.
|
* here, as failures to restore files can be reported later.
|
||||||
*/
|
*/
|
||||||
static void
|
static void createPath (const char *name, int mode)
|
||||||
createPath(const char * name, int mode)
|
|
||||||
{
|
{
|
||||||
char *cp;
|
char *cp;
|
||||||
char *cpOld;
|
char *cpOld;
|
||||||
@ -1100,8 +1038,7 @@ createPath(const char * name, int mode)
|
|||||||
|
|
||||||
cp = strchr (buf, '/');
|
cp = strchr (buf, '/');
|
||||||
|
|
||||||
while (cp)
|
while (cp) {
|
||||||
{
|
|
||||||
cpOld = cp;
|
cpOld = cp;
|
||||||
cp = strchr (cp + 1, '/');
|
cp = strchr (cp + 1, '/');
|
||||||
|
|
||||||
@ -1120,13 +1057,11 @@ createPath(const char * name, int mode)
|
|||||||
* spaces on both sides of the number and with an optional null character
|
* spaces on both sides of the number and with an optional null character
|
||||||
* at the end. Returns -1 on an illegal format.
|
* at the end. Returns -1 on an illegal format.
|
||||||
*/
|
*/
|
||||||
static long
|
static long getOctal (const char *cp, int len)
|
||||||
getOctal(const char * cp, int len)
|
|
||||||
{
|
{
|
||||||
long val;
|
long val;
|
||||||
|
|
||||||
while ((len > 0) && (*cp == ' '))
|
while ((len > 0) && (*cp == ' ')) {
|
||||||
{
|
|
||||||
cp++;
|
cp++;
|
||||||
len--;
|
len--;
|
||||||
}
|
}
|
||||||
@ -1136,14 +1071,12 @@ getOctal(const char * cp, int len)
|
|||||||
|
|
||||||
val = 0;
|
val = 0;
|
||||||
|
|
||||||
while ((len > 0) && isOctal(*cp))
|
while ((len > 0) && isOctal (*cp)) {
|
||||||
{
|
|
||||||
val = val * 8 + *cp++ - '0';
|
val = val * 8 + *cp++ - '0';
|
||||||
len--;
|
len--;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((len > 0) && (*cp == ' '))
|
while ((len > 0) && (*cp == ' ')) {
|
||||||
{
|
|
||||||
cp++;
|
cp++;
|
||||||
len--;
|
len--;
|
||||||
}
|
}
|
||||||
@ -1160,8 +1093,7 @@ getOctal(const char * cp, int len)
|
|||||||
* The number is zero and space padded and possibly null padded.
|
* The number is zero and space padded and possibly null padded.
|
||||||
* Returns TRUE if successful.
|
* Returns TRUE if successful.
|
||||||
*/
|
*/
|
||||||
static int
|
static int putOctal (char *cp, int len, long value)
|
||||||
putOctal(char * cp, int len, long value)
|
|
||||||
{
|
{
|
||||||
int tempLength;
|
int tempLength;
|
||||||
char *tempString;
|
char *tempString;
|
||||||
@ -1180,8 +1112,7 @@ putOctal(char * cp, int len, long value)
|
|||||||
/*
|
/*
|
||||||
* If the string is too large, suppress the leading space.
|
* If the string is too large, suppress the leading space.
|
||||||
*/
|
*/
|
||||||
if (tempLength > len)
|
if (tempLength > len) {
|
||||||
{
|
|
||||||
tempLength--;
|
tempLength--;
|
||||||
tempString++;
|
tempString++;
|
||||||
}
|
}
|
||||||
@ -1230,8 +1161,7 @@ wantFileName(const char * fileName, int fileCount, char ** fileTable)
|
|||||||
/*
|
/*
|
||||||
* Check each of the test paths.
|
* Check each of the test paths.
|
||||||
*/
|
*/
|
||||||
while (fileCount-- > 0)
|
while (fileCount-- > 0) {
|
||||||
{
|
|
||||||
pathName = *fileTable++;
|
pathName = *fileTable++;
|
||||||
|
|
||||||
pathLength = strlen (pathName);
|
pathLength = strlen (pathName);
|
||||||
@ -1242,9 +1172,7 @@ wantFileName(const char * fileName, int fileCount, char ** fileTable)
|
|||||||
if (memcmp (fileName, pathName, pathLength) != 0)
|
if (memcmp (fileName, pathName, pathLength) != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((fileLength == pathLength) ||
|
if ((fileLength == pathLength) || (fileName[pathLength] == '/')) {
|
||||||
(fileName[pathLength] == '/'))
|
|
||||||
{
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1256,5 +1184,3 @@ wantFileName(const char * fileName, int fileCount, char ** fileTable)
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
/* END CODE */
|
/* END CODE */
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
|
|
||||||
#include <linux/unistd.h>
|
#include <linux/unistd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <getopt.h>
|
|
||||||
|
|
||||||
#define __NR_klog __NR_syslog
|
#define __NR_klog __NR_syslog
|
||||||
|
|
||||||
@ -25,56 +24,56 @@
|
|||||||
static inline _syscall3 (int, klog, int, type, char *, b, int, len)
|
static inline _syscall3 (int, klog, int, type, char *, b, int, len)
|
||||||
#endif /* __GLIBC__ */
|
#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];
|
char buf[4096];
|
||||||
int i;
|
int i;
|
||||||
int n;
|
int n;
|
||||||
int c;
|
|
||||||
int level = 0;
|
int level = 0;
|
||||||
int lastc;
|
int lastc;
|
||||||
int cmd = 3;
|
int cmd = 3;
|
||||||
|
|
||||||
while ((c = getopt( argc, argv, "cn:" )) != EOF) {
|
argc--;
|
||||||
switch (c) {
|
argv++;
|
||||||
|
|
||||||
|
/* Parse any options */
|
||||||
|
while (argc && **argv == '-') {
|
||||||
|
while (*++(*argv))
|
||||||
|
switch (**argv) {
|
||||||
case 'c':
|
case 'c':
|
||||||
cmd = 4;
|
cmd = 4;
|
||||||
break;
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
cmd = 8;
|
cmd = 8;
|
||||||
level = atoi(optarg);
|
if (--argc == 0)
|
||||||
|
goto end;
|
||||||
|
level = atoi (*(++argv));
|
||||||
|
--argc;
|
||||||
|
++argv;
|
||||||
break;
|
break;
|
||||||
case '?':
|
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "%s\n", dmesg_usage);
|
goto end;
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
argc -= optind;
|
|
||||||
argv += optind;
|
|
||||||
|
|
||||||
if (argc > 1) {
|
|
||||||
fprintf(stderr, "%s\n", dmesg_usage);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cmd == 8) {
|
if (cmd == 8) {
|
||||||
n = klog (cmd, NULL, level);
|
n = klog (cmd, NULL, level);
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
perror ("klog");
|
perror ("klog");
|
||||||
exit( 1 );
|
exit (FALSE);
|
||||||
}
|
}
|
||||||
exit( 0 );
|
exit (TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
n = klog (cmd, buf, sizeof (buf));
|
n = klog (cmd, buf, sizeof (buf));
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
perror ("klog");
|
perror ("klog");
|
||||||
exit( 1 );
|
exit (FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
lastc = '\n';
|
lastc = '\n';
|
||||||
@ -91,5 +90,9 @@ dmesg_main(int argc, char * * argv)
|
|||||||
}
|
}
|
||||||
if (lastc != '\n')
|
if (lastc != '\n')
|
||||||
putchar ('\n');
|
putchar ('\n');
|
||||||
return 0;
|
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 "internal.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
|
|
||||||
const char more_usage[] = "[file ...]";
|
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)
|
extern int more_main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int c, lines=0;
|
int c, lines=0, input;
|
||||||
int next_page=0, rows = 24;
|
int next_page=0, rows = 24;
|
||||||
#ifdef ERASE_STUFF
|
#ifdef BB_MORE_TERM
|
||||||
int cols=79;
|
int cols;
|
||||||
|
struct winsize win;
|
||||||
#endif
|
#endif
|
||||||
struct stat st;
|
struct stat st;
|
||||||
FILE *file = stdin;
|
FILE *file = stdin;
|
||||||
|
|
||||||
if ( strcmp(*argv,"--help")==0 || strcmp(*argv,"-h")==0 ) {
|
if ( strcmp(*argv,"--help")==0 || strcmp(*argv,"-h")==0 ) {
|
||||||
fprintf(stderr, "Usage: %s %s", *argv, more_usage);
|
fprintf(stderr, "Usage: %s %s", *argv, more_usage);
|
||||||
return(FALSE);
|
exit(FALSE);
|
||||||
}
|
}
|
||||||
argc--;
|
argc--;
|
||||||
argv++;
|
argv++;
|
||||||
@ -48,23 +69,47 @@ extern int more_main(int argc, char **argv)
|
|||||||
file = fopen(*argv, "r");
|
file = fopen(*argv, "r");
|
||||||
if (file == NULL) {
|
if (file == NULL) {
|
||||||
perror("Can't open file");
|
perror("Can't open file");
|
||||||
return(FALSE);
|
exit(FALSE);
|
||||||
}
|
}
|
||||||
fstat(fileno(file), &st);
|
fstat(fileno(file), &st);
|
||||||
fprintf(stderr, "hi\n");
|
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) {
|
while ((c = getc(file)) != EOF) {
|
||||||
if ( next_page ) {
|
if ( next_page ) {
|
||||||
int len=0;
|
int len=0;
|
||||||
next_page = 0;
|
next_page = 0;
|
||||||
lines=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 )),
|
(int) (100*( (double) ftell(file) / (double) st.st_size )),
|
||||||
st.st_size);
|
st.st_size,
|
||||||
|
#ifdef BB_MORE_TERM
|
||||||
|
""
|
||||||
|
#else
|
||||||
|
"\n"
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
getc( stdin);
|
input = getc( stdin);
|
||||||
#ifdef ERASE_STUFF
|
|
||||||
/* Try to erase the "More" message */
|
#ifdef BB_MORE_TERM
|
||||||
|
/* Erase the "More" message */
|
||||||
while(len-- > 0)
|
while(len-- > 0)
|
||||||
putc('\b', stdout);
|
putc('\b', stdout);
|
||||||
while(len++ < cols)
|
while(len++ < cols)
|
||||||
@ -73,7 +118,12 @@ extern int more_main(int argc, char **argv)
|
|||||||
putc('\b', stdout);
|
putc('\b', stdout);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
if (input=='q')
|
||||||
|
goto end;
|
||||||
|
if (input==' ' && c == '\n' )
|
||||||
|
next_page = 1;
|
||||||
if ( c == '\n' && ++lines == (rows + 1) )
|
if ( c == '\n' && ++lines == (rows + 1) )
|
||||||
next_page = 1;
|
next_page = 1;
|
||||||
putc(c, stdout);
|
putc(c, stdout);
|
||||||
@ -84,7 +134,10 @@ extern int more_main(int argc, char **argv)
|
|||||||
argc--;
|
argc--;
|
||||||
argv++;
|
argv++;
|
||||||
}
|
}
|
||||||
return(TRUE);
|
end:
|
||||||
|
#ifdef BB_MORE_TERM
|
||||||
|
gotsig(0);
|
||||||
|
#endif
|
||||||
|
exit(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user