#include #include #include #include #include #include #include #include #include #include #include #include /* Directory: / Symlink: @ Executable: * FIFO: | Socket: = */ #define T_DIR 0x2f #define T_LNK 0x40 #define T_EXC 0x2a #define T_FFO 0x7c #define T_SOC 0x3d #define MON(n) (n == 0) ? "Jan" :\ (n == 1) ? "Feb" :\ (n == 2) ? "Mar" :\ (n == 3) ? "Apr" :\ (n == 4) ? "May" :\ (n == 5) ? "Jun" :\ (n == 6) ? "Jul" :\ (n == 7) ? "Aug" :\ (n == 8) ? "Sep" :\ (n == 9) ? "Oct" :\ (n ==10) ? "Nov" :\ (n ==11) ? "Dec" : "n/a" int no, fi, di, ln, pi, so, bd, cd, or, ex; void sls(char *); char *itos(int); char e[4086][2][200]; int main(int argc, char *argv[]) { int i, j, n, p, z; char *cenv = getenv("LS_COLORS"), *cwd; struct stat _stat; struct dirent **dircontents; i = j = p = z = 0; if (cenv) while (*cenv) { /* get the environmental stuff for the color options and fill it in the array ( e[][][] ) */ switch(*cenv) { case ':': if (z) { e[p][1][j] = 0; p++; } /* is this our first time? */ else z = 1; i = j = 0; break; case '=': e[p][0][j] = 0; i = 1; j = 0; break; default: e[p][i][j] = *cenv; j++; break; } cenv++; } if (p) for (i=0; id_name); return 0; } for (i=1; id_name); chdir(cwd); } else sls(argv[i]); } return 0; } void sls(char *name) { int islnk = 0; char *_user, *_group, lbuffer[256]; struct tm *time_s; struct passwd *_pinfo; struct group *_ginfo; struct stat _stat; if ((lstat(name, &_stat)) < 0) { fprintf(stderr, "%s: %s\n", name, strerror(errno)); return; } if ((_stat.st_mode & S_IFMT) == S_IFLNK) { islnk = 1; memset(lbuffer, 0, 256); readlink(name, lbuffer, 256); } time_s = localtime(&_stat.st_mtime); /* get modification time */ _user = ((_pinfo = getpwuid(_stat.st_uid)) == 0) ? itos(_stat.st_uid) : _pinfo->pw_name; /* owner */ _group = ((_ginfo = getgrgid(_stat.st_gid)) == 0) ? itos(_stat.st_gid) : _ginfo->gr_name; /* group */ printf("%c%c%c%c%c%c%c%c%c%c %3d %8.8s %8.8s%9d %s %2d %2.2d:%2.2d " "\033[%sm%s\033[0m%c%s%s\n", /* i dunno, too complex to comment just get everything we want to know about our file in the form: mode links user group size modification-time filename result is like any other ls */ ((_stat.st_mode & S_IFMT) == S_IFLNK) ? 'l' : /* symlink */ ((_stat.st_mode & S_IFMT) == S_IFDIR) ? 'd' : /* directory */ ((_stat.st_mode & S_IFMT) == S_IFCHR) ? 'c' : /* char device */ ((_stat.st_mode & S_IFMT) == S_IFBLK) ? 'b' : /* block device */ ((_stat.st_mode & S_IFMT) == S_IFIFO) ? 'p' : /* pipe */ ((_stat.st_mode & S_IFMT) == S_IFSOCK) ? 's' : '-', /* socket */ (_stat.st_mode & S_IRUSR) ? 'r' : '-', /* user readable */ (_stat.st_mode & S_IWUSR) ? 'w' : '-', /* user writable */ ((_stat.st_mode & S_IXUSR) && !(_stat.st_mode & S_ISUID)) ? 'x' : /* user executable */ (_stat.st_mode & S_ISUID) ? 's' : '-', /* setuid */ (_stat.st_mode & S_IRGRP) ? 'r' : '-', /* group readable */ (_stat.st_mode & S_IWGRP) ? 'w' : '-', /* group writable */ ((_stat.st_mode & S_IXGRP) && !(_stat.st_mode & S_ISGID)) ? 'x' : /* group executable */ (_stat.st_mode & S_ISGID) ? 's' : '-', /* setgid */ (_stat.st_mode & S_IROTH) ? 'r' : '-', /* other readable */ (_stat.st_mode & S_IWOTH) ? 'w' : '-', /* other writable */ ((_stat.st_mode & S_IXOTH) && !(_stat.st_mode & S_ISVTX)) ? 'x' : /* other executable */ (_stat.st_mode & S_ISVTX) ? 't' : '-', /* sticky */ _stat.st_nlink, _user, _group, _stat.st_size, MON(time_s->tm_mon), time_s->tm_mday, time_s->tm_hour, time_s->tm_min, /* color starts here */ ((_stat.st_mode & S_IFMT) == S_IFLNK) ? e[ln][1] : ((_stat.st_mode & S_IFMT) == S_IFDIR) ? e[di][1] : ((_stat.st_mode & S_IFMT) == S_IFCHR) ? e[cd][1] : ((_stat.st_mode & S_IFMT) == S_IFBLK) ? e[bd][1] : ((_stat.st_mode & S_IFMT) == S_IFIFO) ? e[pi][1] : ((_stat.st_mode & S_IFMT) == S_IFSOCK)? e[so][1] : ((_stat.st_mode & S_IXUSR) && !(_stat.st_mode & S_ISUID)) ? e[ex][1] : (_stat.st_mode & S_ISUID) ? e[ex][1] : ((_stat.st_mode & S_IXGRP) && !(_stat.st_mode & S_ISGID)) ? e[ex][1] : (_stat.st_mode & S_ISGID) ? e[ex][1] : ((_stat.st_mode & S_IXOTH) && !(_stat.st_mode & S_ISVTX)) ? e[ex][1] : (_stat.st_mode & S_ISVTX) ? e[ex][1] : e[fi][1], name, /* types */ ((_stat.st_mode & S_IFMT) == S_IFLNK) ? T_LNK : ((_stat.st_mode & S_IFMT) == S_IFDIR) ? T_DIR : ((_stat.st_mode & S_IFMT) == S_IFIFO) ? T_FFO : ((_stat.st_mode & S_IFMT) == S_IFSOCK)? T_SOC : (_stat.st_mode & S_IXUSR) ? T_EXC : (_stat.st_mode & S_IXGRP) ? T_EXC : (_stat.st_mode & S_IXOTH) ? T_EXC : ' ', /* if this is a symlink, print where it'll take us */ (islnk) ? " -> " : "", (islnk) ? lbuffer : ""); } /* simple function to convert from integers to strings needed if the owner or group names are missing. uses sprintf */ char *itos(int number) { char *_buffer; if ((_buffer = malloc(10)) == NULL) { fprintf(stderr, "unable to allocate memory\n"); exit(1); } memset(_buffer, 0, 10); sprintf(_buffer, "%d", number); return _buffer; }