取自busybox-0.60.3中的ls.c,并且经过整理,使得能编译运行
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <signal.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <time.h>
#include <stdarg.h>
#include <pwd.h>
#include <grp.h>
#define MAJOR(dev) (((dev)>>8)&0xff)
#define MINOR(dev) ((dev)&0xff)
#define TYPEINDEX(mode) (((mode) >> 12) & 0x0f)
#define TYPECHAR(mode) ("0pcCd?bB-?l?s???" [TYPEINDEX(mode)])
#define APPCHAR(mode) ("\0|\0\0/\0\0\0\0\0@\0=\0\0\0" [TYPEINDEX(mode)])
#define COLOR(mode) ("\000\043\043\043\042\000\043\043"\
"\000\000\044\000\043\000\000\040" [TYPEINDEX(mode)])
#define ATTR(mode) ("\00\00\01\00\01\00\01\00"\
"\00\00\01\00\01\00\00\01" [TYPEINDEX(mode)])
enum {
KILOBYTE = 1024,
MEGABYTE = (KILOBYTE*1024),
GIGABYTE = (MEGABYTE*1024)
};
/* Some useful definitions */
#define FALSE ((int) 0)
#define TRUE ((int) 1)
#define SKIP ((int) 2)
enum {
TERMINAL_WIDTH = 80, /* use 79 if terminal has linefold bug */
COLUMN_WIDTH = 14, /* default if AUTOWIDTH not defined */
COLUMN_GAP = 2, /* includes the file type char */
};
/* what is the overall style of the listing */
enum {
STYLE_AUTO = 0,
STYLE_LONG = 1, /* one record per line, extended info */
STYLE_SINGLE = 2, /* one record per line */
STYLE_COLUMNS = 3 /* fill columns */
};
/* what file information will be listed */
#define LIST_INO (1<<0)
#define LIST_BLOCKS (1<<1)
#define LIST_MODEBITS (1<<2)
#define LIST_NLINKS (1<<3)
#define LIST_ID_NAME (1<<4)
#define LIST_ID_NUMERIC (1<<5)
#define LIST_SIZE (1<<6)
#define LIST_DEV (1<<7)
#define LIST_DATE_TIME (1<<8)
#define LIST_FULLTIME (1<<9)
#define LIST_FILENAME (1<<10)
#define LIST_SYMLINK (1<<11)
#define LIST_FILETYPE (1<<12)
#define LIST_EXEC (1<<13)
/* what files will be displayed */
#define DISP_NORMAL (0) /* show normal filenames */
#define DISP_DIRNAME (1<<0) /* 2 or more items? label directories */
#define DISP_HIDDEN (1<<1) /* show filenames starting with . */
#define DISP_DOT (1<<2) /* show . and .. */
#define DISP_NOLIST (1<<3) /* show directory as itself, not contents */
#define DISP_RECURSIVE (1<<4) /* show directory and everything below it */
#define DISP_ROWS (1<<5) /* print across rows */
#define ERR_EXIT(m) (perror_msg(m), exit(EXIT_FAILURE))
/* how will the files be sorted */
static const int SORT_FORWARD = 0; /* sort in reverse order */
static const int SORT_REVERSE = 1; /* sort in reverse order */
static const int SORT_NAME = 2; /* sort by file name */
static const int SORT_SIZE = 3; /* sort by file size */
static const int SORT_ATIME = 4; /* sort by last access time */
static const int SORT_CTIME = 5; /* sort by last change time */
static const int SORT_MTIME = 6; /* sort by last modification time */
static const int SORT_VERSION = 7; /* sort by version */
static const int SORT_EXT = 8; /* sort by file name extension */
static const int SORT_DIR = 9; /* sort by file or directory */
/* which of the three times will be used */
static const int TIME_MOD = 0;
static const int TIME_CHANGE = 1;
static const int TIME_ACCESS = 2;
#define LIST_SHORT (LIST_FILENAME)
#define LIST_ISHORT (LIST_INO | LIST_FILENAME)
#define LIST_LONG (LIST_MODEBITS | LIST_NLINKS | LIST_ID_NAME | \
LIST_SIZE | LIST_DATE_TIME | LIST_FILENAME | \
LIST_SYMLINK)
#define LIST_ILONG (LIST_INO | LIST_LONG)
static const int SPLIT_DIR = 0;
static const int SPLIT_FILE = 1;
static const int SPLIT_SUBDIR = 2;
#define TYPEINDEX(mode) (((mode) >> 12) & 0x0f)
#define APPCHAR(mode) ("\0|\0\0/\0\0\0\0\0@\0=\0\0\0" [TYPEINDEX(mode)])
/* colored LS support */
static int show_color = 0;
#define COLOR(mode) ("\000\043\043\043\042\000\043\043"\
"\000\000\044\000\043\000\000\040" [TYPEINDEX(mode)])
#define ATTR(mode) ("\00\00\01\00\01\00\01\00"\
"\00\00\01\00\01\00\00\01" [TYPEINDEX(mode)])
#define show_usage() usage(argv[0])
/*
* a directory entry and its stat info are stored here
*/
struct dnode { /* the basic node */
char *name; /* the dir entry name */
char *fullname; /* the dir path name */
struct stat dstat; /* the file stat info */
struct dnode *next; /* point at the next node */
};
typedef struct dnode dnode_t;
static struct dnode **list_dir(char *);
static struct dnode **dnalloc(int);
static int list_single(struct dnode *);
static unsigned int disp_opts;
static unsigned int style_fmt;
static unsigned int list_fmt;
static unsigned int sort_opts;
static unsigned int sort_order;
static unsigned int time_fmt;
static unsigned int follow_links=FALSE;
static unsigned short column = 0;
static unsigned short terminal_width = TERMINAL_WIDTH;
static unsigned short column_width = COLUMN_WIDTH;
static unsigned short tabstops = COLUMN_GAP;
static int status = EXIT_SUCCESS;
static unsigned long ls_disp_hr = 0;
#define TYPEINDEX(mode) (((mode) >> 12) & 0x0f)
#define TYPECHAR(mode) ("0pcCd?bB-?l?s???" [TYPEINDEX(mode)])
/* The special bits. If set, display SMODE0/1 instead of MODE0/1 */
static const mode_t SBIT[] = {
0, 0, S_ISUID,
0, 0, S_ISGID,
0, 0, S_ISVTX
};
/* The 9 mode bits to test */
static const mode_t MBIT[] = {
S_IRUSR, S_IWUSR, S_IXUSR,
S_IRGRP, S_IWGRP, S_IXGRP,
S_IROTH, S_IWOTH, S_IXOTH
};
static const char MODE1[] = "rwxrwxrwx";
static const char MODE0[] = "---------";
static const char SMODE1[] = "..s..s..t";
static const char SMODE0[] = "..S..S..T";
char * last_char_is(const char *s, int c);
const char *make_human_readable_str(unsigned long size,
unsigned long block_size,
unsigned long display_unit);
const char *mode_string(int mode);
extern char * safe_strncpy(char *dst, const char *src, size_t size);
extern char * xstrdup (const char *s);
extern char * xstrndup (const char *s, int n);
extern char *concat