⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ls.c

📁 手机嵌入式Linux下可用的busybox源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* vi: set sw=4 ts=4: *//* * tiny-ls.c version 0.1.0: A minimalist 'ls' * Copyright (C) 1996 Brian Candler <B.Candler@pobox.com> * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *//* * To achieve a small memory footprint, this version of 'ls' doesn't do any * file sorting, and only has the most essential command line switches * (i.e., the ones I couldn't live without :-) All features which involve * linking in substantial chunks of libc can be disabled. * * Although I don't really want to add new features to this program to * keep it small, I *am* interested to receive bug fixes and ways to make * it more portable. * * KNOWN BUGS: * 1. ls -l of a directory doesn't give "total <blocks>" header * 2. ls of a symlink to a directory doesn't list directory contents * 3. hidden files can make column width too large * * NON-OPTIMAL BEHAVIOUR: * 1. autowidth reads directories twice * 2. if you do a short directory listing without filetype characters *    appended, there's no need to stat each one * PORTABILITY: * 1. requires lstat (BSD) - how do you do it without? */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 */};/************************************************************************/#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 "busybox.h"#ifdef BB_FEATURE_LS_TIMESTAMPS#include <time.h>#endif#ifndef MAJOR#define MAJOR(dev) (((dev)>>8)&0xff)#define MINOR(dev) ((dev)&0xff)#endif/* 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 */};/* 51306 lrwxrwxrwx  1 root     root         2 May 11 01:43 /bin/view -> vi* *//* 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 */#ifdef BB_FEATURE_LS_SORTFILES/* 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 */#endif#ifdef BB_FEATURE_LS_TIMESTAMPS/* 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;#endif#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 TYPECHAR(mode)  ("0pcCd?bB-?l?s???" [TYPEINDEX(mode)])#if defined(BB_FEATURE_LS_FILETYPES) || defined(BB_FEATURE_LS_COLOR)#define APPCHAR(mode)   ("\0|\0\0/\0\0\0\0\0@\0=\0\0\0" [TYPEINDEX(mode)])#endif/* colored LS support by JaWi, janwillem.janssen@lxtreme.nl */#ifdef BB_FEATURE_LS_COLORstatic 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)])#endif/* * 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 entry 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;#ifdef BB_FEATURE_LS_SORTFILESstatic unsigned int sort_opts;static unsigned int sort_order;#endif#ifdef BB_FEATURE_LS_TIMESTAMPSstatic unsigned int time_fmt;#endif#ifdef BB_FEATURE_LS_FOLLOWLINKSstatic unsigned int follow_links=FALSE;#endifstatic unsigned short column = 0;#ifdef BB_FEATURE_AUTOWIDTHstatic unsigned short terminal_width = TERMINAL_WIDTH;static unsigned short column_width = COLUMN_WIDTH;static unsigned short tabstops = COLUMN_GAP;#elsestatic unsigned short column_width = COLUMN_WIDTH;#endifstatic int status = EXIT_SUCCESS;#ifdef BB_FEATURE_HUMAN_READABLEstatic unsigned long ls_disp_hr = 0;#endifstatic int my_stat(struct dnode *cur){#ifdef BB_FEATURE_LS_FOLLOWLINKS	if (follow_links == TRUE) {		if (stat(cur->fullname, &cur->dstat)) {			perror_msg("%s", cur->fullname);			status = EXIT_FAILURE;			free(cur->fullname);			free(cur);			return -1;		}	} else#endif	if (lstat(cur->fullname, &cur->dstat)) {		perror_msg("%s", cur->fullname);		status = EXIT_FAILURE;		free(cur->fullname);		free(cur);		return -1;	}	return 0;}static void newline(void){    if (column > 0) {        putchar('\n');        column = 0;    }}/*----------------------------------------------------------------------*/#ifdef BB_FEATURE_LS_COLORstatic char fgcolor(mode_t mode){	/* Check if the file is missing */	if ( errno == ENOENT ) {		errno = 0;		/* Color it red! */	    return '\037';	}	if ( LIST_EXEC && S_ISREG( mode )	    && ( mode & ( S_IXUSR | S_IXGRP | S_IXOTH ) ) ) 		return COLOR(0xF000);	/* File is executable ... */	return COLOR(mode);}/*----------------------------------------------------------------------*/static char bgcolor(mode_t mode){	if ( LIST_EXEC && S_ISREG( mode )	    && ( mode & ( S_IXUSR | S_IXGRP | S_IXOTH ) ) ) 		return ATTR(0xF000);	/* File is executable ... */	return ATTR(mode);}#endif/*----------------------------------------------------------------------*/#if defined(BB_FEATURE_LS_FILETYPES) || defined(BB_FEATURE_LS_COLOR)static char append_char(mode_t mode){	if ( !(list_fmt & LIST_FILETYPE))		return '\0';	if ((list_fmt & LIST_EXEC) && S_ISREG(mode)	    && (mode & (S_IXUSR | S_IXGRP | S_IXOTH))) return '*';		return APPCHAR(mode);}#endif/*----------------------------------------------------------------------*/static void nexttabstop( void ){	static short nexttab= 0;	int n=0;	if (column > 0) {		n= nexttab - column;		if (n < 1) n= 1;		while (n--) {			putchar(' ');			column++;		}	}	nexttab= column + column_width + COLUMN_GAP; }/*----------------------------------------------------------------------*/static int is_subdir(struct dnode *dn){	return (S_ISDIR(dn->dstat.st_mode) && strcmp(dn->name, ".") != 0 &&			strcmp(dn->name, "..") != 0);}static int countdirs(struct dnode **dn, int nfiles){	int i, dirs;	if (dn==NULL || nfiles < 1) return(0);	dirs= 0;	for (i=0; i<nfiles; i++) {		if (S_ISDIR(dn[i]->dstat.st_mode)) dirs++;	}	return(dirs);}static int countsubdirs(struct dnode **dn, int nfiles){	int i, subdirs;	if (dn == NULL || nfiles < 1) return 0;	subdirs = 0;	for (i = 0; i < nfiles; i++)		if (is_subdir(dn[i]))			subdirs++;	return subdirs;}static int countfiles(struct dnode **dnp){	int nfiles;	struct dnode *cur;	if (dnp == NULL) return(0);	nfiles= 0;	for (cur= dnp[0];  cur->next != NULL ; cur= cur->next) nfiles++;	nfiles++;	return(nfiles);}/* get memory to hold an array of pointers */static struct dnode **dnalloc(int num){	struct dnode **p;	if (num < 1) return(NULL);	p= (struct dnode **)xcalloc((size_t)num, (size_t)(sizeof(struct dnode *)));	return(p);}#ifdef BB_FEATURE_LS_RECURSIVEstatic void dfree(struct dnode **dnp){	struct dnode *cur, *next;	if(dnp == NULL) return;	cur=dnp[0];	while (cur != NULL) {		if (cur->fullname != NULL) free(cur->fullname);	/* free the filename */		next= cur->next;		free(cur);				/* free the dnode */		cur= next;	}	free(dnp);	/* free the array holding the dnode pointers */}#endifstatic struct dnode **splitdnarray(struct dnode **dn, int nfiles, int which){	int dncnt, i, d;	struct dnode **dnp;	if (dn==NULL || nfiles < 1) return(NULL);	/* count how many dirs and regular files there are */	if (which == SPLIT_SUBDIR)		dncnt = countsubdirs(dn, nfiles);	else {		dncnt= countdirs(dn, nfiles); /* assume we are looking for dirs */		if (which == SPLIT_FILE)			dncnt= nfiles - dncnt;  /* looking for files */	}	/* allocate a file array and a dir array */	dnp= dnalloc(dncnt);	/* copy the entrys into the file or dir array */	for (d= i=0; i<nfiles; i++) {		if (which == SPLIT_DIR) {			if (S_ISDIR(dn[i]->dstat.st_mode)) {				dnp[d++]= dn[i];			}  /* else skip the file */		} else if (which == SPLIT_SUBDIR) {			if (is_subdir(dn[i])) {				dnp[d++]= dn[i];			}  /* else skip the file or dir */		} else {			if (!(S_ISDIR(dn[i]->dstat.st_mode))) {				dnp[d++]= dn[i];			}  /* else skip the dir */		}	}	return(dnp);}/*----------------------------------------------------------------------*/#ifdef BB_FEATURE_LS_SORTFILESstatic int sortcmp(struct dnode *d1, struct dnode *d2){	int cmp, dif;	cmp= 0;	if (sort_opts == SORT_SIZE) {		dif= (int)(d1->dstat.st_size - d2->dstat.st_size);	} else if (sort_opts == SORT_ATIME) {		dif= (int)(d1->dstat.st_atime - d2->dstat.st_atime);	} else if (sort_opts == SORT_CTIME) {		dif= (int)(d1->dstat.st_ctime - d2->dstat.st_ctime);	} else if (sort_opts == SORT_MTIME) {		dif= (int)(d1->dstat.st_mtime - d2->dstat.st_mtime);	} else if (sort_opts == SORT_DIR) {		dif= S_ISDIR(d1->dstat.st_mode) - S_ISDIR(d2->dstat.st_mode);	/* } else if (sort_opts == SORT_VERSION) { */	/* } else if (sort_opts == SORT_EXT) { */	} else {    /* assume SORT_NAME */		dif= 0;	}	if (dif > 0) cmp= -1;	if (dif < 0) cmp=  1;	if (dif == 0) {		/* sort by name- may be a tie_breaker for time or size cmp */		dif= strcmp(d1->name, d2->name);		if (dif > 0) cmp=  1;		if (dif < 0) cmp= -1;	}	if (sort_order == SORT_REVERSE) {		cmp=  -1 * cmp;	}	return(cmp);}/*----------------------------------------------------------------------*/static void shellsort(struct dnode **dn, int size){	struct dnode *temp;	int gap, i, j;	/* shell short the array */	if(dn==NULL || size < 2) return;	for (gap= size/2; gap>0; gap /=2) {		for (i=gap; i<size; i++) {			for (j= i-gap; j>=0; j-=gap) {				if (sortcmp(dn[j], dn[j+gap]) <= 0)					break;				/* they are out of order, swap them */				temp= dn[j];				dn[j]= dn[j+gap];				dn[j+gap]= temp;			}		}	}}#endif/*----------------------------------------------------------------------*/static void showfiles(struct dnode **dn, int nfiles){	int i, ncols, nrows, row, nc;#ifdef BB_FEATURE_AUTOWIDTH	int len;#endif	if(dn==NULL || nfiles < 1) return;#ifdef BB_FEATURE_AUTOWIDTH	/* find the longest file name-  use that as the column width */	column_width= 0;	for (i=0; i<nfiles; i++) {		len= strlen(dn[i]->name) +			((list_fmt & LIST_INO) ? 8 : 0) +			((list_fmt & LIST_BLOCKS) ? 5 : 0)			;		if (column_width < len) 			column_width= len;	}	if (column_width >= 1)		ncols = (int)(terminal_width / (column_width + COLUMN_GAP));	else {		ncols = 1;		column_width = COLUMN_WIDTH;	}#else	ncols= TERMINAL_WIDTH;#endif	switch (style_fmt) {		case STYLE_LONG:	/* one record per line, extended info */		case STYLE_SINGLE:	/* one record per line */			ncols= 1;			break;	}	if (ncols > 1) {		nrows = nfiles / ncols;	} else {		nrows = nfiles;		ncols = 1;	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -