ls.c revision 327e696808910f8e49370079f8d7f4db8cbe3820
1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h> 2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h> 3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h> 4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/types.h> 5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <dirent.h> 6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h> 7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/stat.h> 9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unistd.h> 10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <time.h> 11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <pwd.h> 13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <grp.h> 14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <linux/kdev_t.h> 16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// bits for flags argument 18b33d3415b6c63f7b22e0863a2ac594feab9171cfAndy McFadden#define LIST_LONG (1 << 0) 19b33d3415b6c63f7b22e0863a2ac594feab9171cfAndy McFadden#define LIST_ALL (1 << 1) 20b33d3415b6c63f7b22e0863a2ac594feab9171cfAndy McFadden#define LIST_RECURSIVE (1 << 2) 21b33d3415b6c63f7b22e0863a2ac594feab9171cfAndy McFadden#define LIST_DIRECTORIES (1 << 3) 22327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden#define LIST_SIZE (1 << 4) 23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// fwd 25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int listpath(const char *name, int flags); 26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic char mode2kind(unsigned mode) 28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch(mode & S_IFMT){ 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case S_IFSOCK: return 's'; 31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case S_IFLNK: return 'l'; 32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case S_IFREG: return '-'; 33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case S_IFDIR: return 'd'; 34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case S_IFBLK: return 'b'; 35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case S_IFCHR: return 'c'; 36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case S_IFIFO: return 'p'; 37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project default: return '?'; 38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void mode2str(unsigned mode, char *out) 42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *out++ = mode2kind(mode); 44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *out++ = (mode & 0400) ? 'r' : '-'; 46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *out++ = (mode & 0200) ? 'w' : '-'; 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(mode & 04000) { 48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *out++ = (mode & 0100) ? 's' : 'S'; 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *out++ = (mode & 0100) ? 'x' : '-'; 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *out++ = (mode & 040) ? 'r' : '-'; 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *out++ = (mode & 020) ? 'w' : '-'; 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(mode & 02000) { 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *out++ = (mode & 010) ? 's' : 'S'; 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *out++ = (mode & 010) ? 'x' : '-'; 58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *out++ = (mode & 04) ? 'r' : '-'; 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *out++ = (mode & 02) ? 'w' : '-'; 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(mode & 01000) { 62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *out++ = (mode & 01) ? 't' : 'T'; 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *out++ = (mode & 01) ? 'x' : '-'; 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *out = 0; 67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void user2str(unsigned uid, char *out) 70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct passwd *pw = getpwuid(uid); 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(pw) { 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strcpy(out, pw->pw_name); 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sprintf(out, "%d", uid); 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void group2str(unsigned gid, char *out) 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct group *gr = getgrgid(gid); 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(gr) { 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strcpy(out, gr->gr_name); 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sprintf(out, "%d", gid); 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 89327e696808910f8e49370079f8d7f4db8cbe3820Andy McFaddenstatic int listfile_size(const char *path, int flags) 90327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden{ 91327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden struct stat s; 92327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden 93327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden if (lstat(path, &s) < 0) 94327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden return -1; 95327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden 96327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden /* blocks are 512 bytes, we want output to be KB */ 97327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden printf("%lld %s\n", s.st_blocks / 2, path); 98327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden return 0; 99327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden} 100327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden 101327e696808910f8e49370079f8d7f4db8cbe3820Andy McFaddenstatic int listfile_long(const char *path, int flags) 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct stat s; 104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char date[32]; 105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char mode[16]; 106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char user[16]; 107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char group[16]; 108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const char *name; 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* name is anything after the final '/', or the whole path if none*/ 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project name = strrchr(path, '/'); 112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(name == 0) { 113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project name = path; 114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project name++; 116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(lstat(path, &s) < 0) { 119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mode2str(s.st_mode, mode); 123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project user2str(s.st_uid, user); 124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project group2str(s.st_gid, group); 125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project strftime(date, 32, "%Y-%m-%d %H:%M", localtime((const time_t*)&s.st_mtime)); 127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project date[31] = 0; 128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// 12345678901234567890123456789012345678901234567890123456789012345678901234567890 130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// MMMMMMMM UUUUUUUU GGGGGGGGG XXXXXXXX YYYY-MM-DD HH:MM NAME (->LINK) 131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project switch(s.st_mode & S_IFMT) { 133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case S_IFBLK: 134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case S_IFCHR: 135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printf("%s %-8s %-8s %3d, %3d %s %s\n", 136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mode, user, group, 137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project (int) MAJOR(s.st_rdev), (int) MINOR(s.st_rdev), 138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project date, name); 139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case S_IFREG: 141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printf("%s %-8s %-8s %8d %s %s\n", 142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mode, user, group, (int) s.st_size, date, name); 143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project case S_IFLNK: { 145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char linkto[256]; 146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int len; 147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project len = readlink(path, linkto, 256); 149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(len < 0) return -1; 150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(len > 255) { 152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project linkto[252] = '.'; 153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project linkto[253] = '.'; 154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project linkto[254] = '.'; 155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project linkto[255] = 0; 156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project linkto[len] = 0; 158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printf("%s %-8s %-8s %s %s -> %s\n", 161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mode, user, group, date, name, linkto); 162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project break; 163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project default: 165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printf("%s %-8s %-8s %s %s\n", 166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mode, user, group, date, name); 167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 172327e696808910f8e49370079f8d7f4db8cbe3820Andy McFaddenstatic int listfile(const char *dirname, const char *filename, int flags) 173327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden{ 174327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden if ((flags & (LIST_LONG | LIST_SIZE)) == 0) { 175327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden printf("%s\n", filename); 176327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden return 0; 177327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden } 178327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden 179327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden char tmp[4096]; 180327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden const char* pathname = filename; 181327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden 182327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden if (dirname != NULL) { 183327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden snprintf(tmp, sizeof(tmp), "%s/%s", dirname, filename); 184327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden pathname = tmp; 185327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden } else { 186327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden pathname = filename; 187327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden } 188327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden 189327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden if ((flags & LIST_LONG) != 0) { 190327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden return listfile_long(pathname, flags); 191327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden } else /*((flags & LIST_SIZE) != 0)*/ { 192327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden return listfile_size(pathname, flags); 193327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden } 194327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden} 195327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden 196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int listdir(const char *name, int flags) 197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char tmp[4096]; 199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project DIR *d; 200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct dirent *de; 201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project d = opendir(name); 203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(d == 0) { 204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fprintf(stderr, "opendir failed, %s\n", strerror(errno)); 205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while((de = readdir(d)) != 0){ 209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) continue; 210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(de->d_name[0] == '.' && (flags & LIST_ALL) == 0) continue; 211327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden 212327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden listfile(name, de->d_name, flags); 213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (flags & LIST_RECURSIVE) { 216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project rewinddir(d); 217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while ((de = readdir(d)) != 0) { 219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct stat s; 220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int err; 221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) 223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (de->d_name[0] == '.' && (flags & LIST_ALL) == 0) 225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 227327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden if (!strcmp(name, "/")) 228327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden snprintf(tmp, sizeof(tmp), "/%s", de->d_name); 229327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden else 230327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden snprintf(tmp, sizeof(tmp), "%s/%s", name, de->d_name); 231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* 233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * If the name ends in a '/', use stat() so we treat it like a 234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * directory even if it's a symlink. 235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (tmp[strlen(tmp)-1] == '/') 237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err = stat(tmp, &s); 238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err = lstat(tmp, &s); 240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (err < 0) { 242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project perror(tmp); 243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project closedir(d); 244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (S_ISDIR(s.st_mode)) { 248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printf("\n%s:\n", tmp); 249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project listdir(tmp, flags); 250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project closedir(d); 255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int listpath(const char *name, int flags) 259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct stat s; 261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int err; 262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project /* 264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * If the name ends in a '/', use stat() so we treat it like a 265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * directory even if it's a symlink. 266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (name[strlen(name)-1] == '/') 268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err = stat(name, &s); 269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err = lstat(name, &s); 271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (err < 0) { 273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project perror(name); 274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 277b33d3415b6c63f7b22e0863a2ac594feab9171cfAndy McFadden if ((flags & LIST_DIRECTORIES) == 0 && S_ISDIR(s.st_mode)) { 278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (flags & LIST_RECURSIVE) 279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printf("\n%s:\n", name); 280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return listdir(name, flags); 281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 282327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden /* yeah this calls stat() again*/ 283327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden return listfile(NULL, name, flags); 284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint ls_main(int argc, char **argv) 288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int flags = 0; 290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int listed = 0; 291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(argc > 1) { 293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int i; 294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int err = 0; 295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for (i = 1; i < argc; i++) { 297327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden if (!strcmp(argv[i], "-l")) { 298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project flags |= LIST_LONG; 299327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden } else if (!strcmp(argv[i], "-s")) { 300327e696808910f8e49370079f8d7f4db8cbe3820Andy McFadden flags |= LIST_SIZE; 301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (!strcmp(argv[i], "-a")) { 302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project flags |= LIST_ALL; 303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (!strcmp(argv[i], "-R")) { 304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project flags |= LIST_RECURSIVE; 305b33d3415b6c63f7b22e0863a2ac594feab9171cfAndy McFadden } else if (!strcmp(argv[i], "-d")) { 306b33d3415b6c63f7b22e0863a2ac594feab9171cfAndy McFadden flags |= LIST_DIRECTORIES; 307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project listed++; 309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(listpath(argv[i], flags) != 0) { 310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project err = EXIT_FAILURE; 311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (listed > 0) return err; 316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // list working directory if no files or directories were specified 319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return listpath(".", flags); 320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 321