More stuff...

This commit is contained in:
Eric Andersen 1999-10-12 22:26:06 +00:00
parent 2ce1edcf54
commit 3cf52d1958
23 changed files with 2740 additions and 2938 deletions

View File

@ -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 */

View File

@ -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
View File

@ -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++;
} }

View File

@ -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++;
} }

View File

@ -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);
}

View File

@ -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");

View File

@ -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
View File

@ -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
View File

@ -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
View File

@ -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);
} }

View File

@ -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
View File

@ -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 */

View File

@ -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
View File

@ -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);
} }

View File

@ -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
View File

@ -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);
} }

View File

@ -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
View File

@ -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");

View File

@ -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
View File

@ -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
View File

@ -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 */

View File

@ -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);
} }

View File

@ -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);
} }