/*
1.尝试实现ls命令的功能 加选项-l -a -i -h
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
#include <pwd.h>
#include <grp.h> #define MAX 1024 static int myls_l(char *optarg);
static void ls_all(char *path);
static int myls_a(char *path);
static int is_dir(char *path);
static void myls_i(char *path);
static void myls_i_notdir(char *path);
static int myls_h(char *path); int main(int argc, char *argv[])
{
int c;
char *str = "-l:a:i:h:";
if (argc < )
return -; while () {
if ((c = getopt(argc, argv, str)) == -)
break;
switch (c) {
case 'l':
is_dir(optarg) ? ls_all(optarg) : myls_l(optarg);
break;
case 'a':
is_dir(optarg) ? myls_a(optarg) : puts(optarg);
break;
case 'i':
is_dir(optarg) ? myls_i(optarg) : myls_i_notdir(optarg);
break;
case 'h':
is_dir(optarg) ? myls_h(optarg) : puts(optarg);
break;
case '?':
printf("输入选项错误\n");
break;
case :
printf("错误参数选项%s\n", argv[optind-]);
break;
default:
break;
}
} return ;
} // 单文件显示详细信息 相当于ls -l +文件名
static int myls_l(char *optarg)
{
struct stat buf; if (stat(optarg, &buf) == -) {
perror("STAT()");
return -;
}
// 文件类型
if (S_ISREG(buf.st_mode))
putchar('-');
if (S_ISDIR(buf.st_mode))
putchar('d');
if (S_ISCHR(buf.st_mode))
putchar('c');
if (S_ISBLK(buf.st_mode))
putchar('b');
if (S_ISFIFO(buf.st_mode))
putchar('p');
if ((buf.st_mode & S_IFMT) == S_IFSOCK)
putchar('s');
if ((buf.st_mode & S_IFMT) == S_IFLNK)
putchar('l');
// 权限
if (buf.st_mode & S_IRUSR)
putchar('r');
else
putchar('-');
if (buf.st_mode & S_IWUSR)
putchar('w');
else
putchar('-');
if (buf.st_mode & S_IXUSR) {
if (buf.st_mode & S_ISUID) {
putchar('s');
} else {
putchar('x');
}
}
else
putchar('-');
if (buf.st_mode & S_IRGRP)
putchar('r');
else
putchar('-');
if (buf.st_mode & S_IWGRP)
putchar('w');
else
putchar('-');
if (buf.st_mode & S_IXGRP) {
if (buf.st_mode & S_ISGID) {
putchar('s');
} else {
putchar('x');
}
}
else
putchar('-');
if (buf.st_mode & S_IROTH)
putchar('r');
else
putchar('-');
if (buf.st_mode & S_IWOTH)
putchar('w');
else
putchar('-');
if (buf.st_mode & S_IXOTH) {
if (buf.st_mode & S_ISVTX) {
putchar('t');
} else {
putchar('x');
}
}
else
putchar('-');
// 硬链接
printf(" %zu ", buf.st_nlink);
// 拥有者
struct passwd *pwd = NULL;
pwd = getpwuid(buf.st_uid);
printf("%s ", pwd->pw_name);
// 所属组
struct group *grp = NULL;
grp = getgrgid(buf.st_gid);
printf("%s ", grp->gr_name);
// 文件字节大小
printf("%zu ", buf.st_size);
// 最后更改文件时间
struct tm *tmp = NULL;
char s[MAX] = {};
tmp = localtime(&(buf.st_mtim.tv_sec));
strftime(s, MAX, "%m月 %d %H:%M ", tmp);
printf("%s ", s);
// 文件名
char *ptr = NULL;
if ((ptr = strrchr(optarg, '/')) != NULL) {
printf("%s", ptr+);
} else {
printf("%s", optarg);
} putchar('\n'); return ;
} // 判断该文件名第一个字符是否为隐藏文件和 . .. .asd
static int is_hidden(char *str)
{
if (str[] == '.') {
return ; // 是隐藏文件返回1
}
return ;
} // 相当于 ls -l +目录的路径
static void ls_all(char *path)
{
DIR *dp = NULL;
char str[MAX] = {};
struct dirent *ret_dir = NULL;
dp = opendir(path); while () {
memset(str, '\0', MAX);
strcpy(str, path);
strcat(str, "/");
if ((ret_dir = readdir(dp)) != NULL) {
if (is_hidden(ret_dir->d_name)) //排除隐藏文件
continue;
strcat(str, ret_dir->d_name); //完整路径
myls_l(str); //调用函数
} else { // 目录读取完毕
break;
}
}
closedir(dp);
} // 判断是文件还是目录 是目录返回1 不是返回0
static int is_dir(char *path)
{
struct stat buf;
lstat(path, &buf);
if (!S_ISDIR(buf.st_mode)) {
return ;
} else
return ;
} // 相当于 ls -a +目录的路径 (当前目录下所以文件包含隐藏文件)
static int myls_a(char *path)
{
DIR *dp = NULL;
struct dirent *ptr = NULL; dp = opendir(path);
if (dp == NULL) {
perror("OPENDIR()");
return -;
}
while () {
ptr = readdir(dp); //返回值为结构体类型指针
if (ptr == NULL) {
if (errno) {
perror("READDIR()");
closedir(dp);
return -;
}
break;
}
printf("%s\n", ptr->d_name);
} closedir(dp);
return ;
} // 相当于 ls -i +目录 显示当前目录下所有文件的inode号 (不包含隐藏)
static void myls_i(char *path)
{
DIR *dp = NULL;
struct dirent *entry = NULL;
dp = opendir(path);
while () {
if ((entry = readdir(dp)) == NULL)
break;
if (is_hidden(entry->d_name)) { //隐藏文件
continue;
}
printf("%zu %s\n", entry->d_ino, entry->d_name);
}
} // 相当于 ls -i +文件
static void myls_i_notdir(char *path)
{
struct stat buf;
stat(path, &buf);
printf("%zu %s\n", buf.st_ino, path);
} // 相当于 ls -h +目录 本目录下所有文件(不包含隐藏)
static int myls_h(char *path)
{
DIR *dp = NULL;
struct dirent *ptr = NULL; dp = opendir(path);
if (dp == NULL) {
perror("OPENDIR()");
return -;
}
while () {
ptr = readdir(dp); //返回值为结构体类型指针
if (ptr == NULL) {
if (errno) {
perror("READDIR()");
closedir(dp);
return -;
}
break;
}
if (is_hidden(ptr->d_name)) {
continue;
}
printf("%s\n", ptr->d_name);
} closedir(dp);
return ;
}

2019.03.15王苛震——myls的更多相关文章

  1. 2019.03.15 ZJOI2019模拟赛 解题报告

    得分: \(20+45+15=80\)(三题暴力全写挂...) \(T1\):Lyk Love painting 首先,不难想到二分答案然后\(DP\)验证. 设当前需验证的答案为\(x\),则一个暴 ...

  2. 2019.03.03 - Linux搭建go语言交叉环境

    编译GO 1.6版本以上的需要依赖GO 1.4版本的二进制,并且需要把GOROOT_BOOTSTRAP的路径设置为1.4版本GO的根目录,这样它的bin目录就可以直接使用到1.4版本的GO 搭建go语 ...

  3. PSP(16/03/14-16/03/15)

    //整理了自己过去的时间记录文件,最早用电子版记录是15/04/21,依旧断断续续记录到15/11/21,每月至少三次记录,然而自己并没有对数据进行整理,只是纯粹记录,真是浪费了花在上面的时间.期间八 ...

  4. [2019.03.25]Linux中的查找

    TMUX天下第一 全世界所有用CLI Linux的人都应该用TMUX,我爱它! ======================== 以下是正文 ======================== Linu ...

  5. Data truncation: Incorrect datetime value: 'May 15, 2019 4:15:37 PM

    因为系统在windows下测试过是正常的 windows下的jdk+ windows下安装的mysql 全部cases通过 linux下的jdk + windows下安装的mysql 新增和更新,影响 ...

  6. MyBatis 配置/注解 SQL CRUD 经典解决方案(2019.08.15持续更新)

    本文旨在记录使用各位大神的经典解决方案. 2019.08.14 更新 Mybatis saveOrUpdate SelectKey非主键的使用 MyBatis实现SaveOrUpdate mybati ...

  7. 2019.03.14 ZJOI2019模拟赛 解题报告

    得分: \(100+100+0=200\)(\(T1\)在最后\(2\)分钟写了出来,\(T2\)在最后\(10\)分钟写了出来,反而\(T3\)写了\(4\)个小时爆\(0\)) \(T1\):风王 ...

  8. [2019.03.16]使用DOM操作函数和CSS选择器来针对已有的HTML进行只凭JS的改动

    刚入职的时候看到公司用的HTML日志生成工具附带的Panel,工具不够用,找个Fail还要找半天,于是自己琢磨着添砖加瓦.以前也是个半吊子前端工程师,现在可倒好,想要改页面却连页面生成的模板在哪里都不 ...

  9. 2019.03.25 bzoj4568: [Scoi2016]幸运数字(倍增+线性基)

    传送门 题意:给你一棵带点权的树,多次询问路径的最大异或和. 思路: 线性基上树?? 倍增维护一下就完了. 时间复杂度O(nlog3n)O(nlog^3n)O(nlog3n) 代码: #include ...

随机推荐

  1. alias命令详解

    1.简介: 设置指令的别名,用户可利用alias,自定指令的别名.若仅输入alias,则可列出目前所有的别名设置. alias的效力仅及于该次登入的操作.若要每次登入是即自动设好别名,可在/etc/p ...

  2. layui表格点击排序按钮后,表格绑定事件失效解决方法

    最近项目使用layui较为频繁,遇到了一个麻烦的问题,网上搜索也没有看到同类型的问题,故此记下来. 需求是点击上图右侧表格中某一个单元格,会触发点击事件如下代码: $("table>t ...

  3. 从数据类型 varchar 转换为 numeric 时出错.

    如果说你的数据库字段是varchar,但是存储的数据是数值,在出报表时需要转成int或numeric时,无论怎么样都报错. 错误信息: 消息 8114,级别 16,状态 5,第 1 行 从数据类型 v ...

  4. ARTS打卡计划第一周-Share-系统字典模块的设计

    在软件开发的过程,经常有一些类型的字段信息:性别.学历.职级.车辆类别.公司类型.结算类型等.这些字段有2个特征:1是字段可选的类型是有限,2是字段可能会变化,我们把这种字段描述为字段字段.  本篇文 ...

  5. ElasticSearch 2.X升级到6.X遇到的几个问题

    1.IndexExists检测索引是否存在,更简洁了,可以这样 _ElasticClient.IndexExists(indices : indexName).Exists 2.索引数据的时候,如果数 ...

  6. 微信小程序问题---数据传输长度为 1275870 已经超过最大长度 1048576

    开发微信小程序时,遇到数据传输长度为 1095538 已经超过最大长度 1048576的问题. 这是setData时操作数据过大导致,一般出现在请求返回数据过大,我们又将这个数据一次性用setData ...

  7. 一千行ABAP代码实现Windows传统游戏扫雷

    *&---------------------------------------------------------------------* *& Report ZCHENH087 ...

  8. LocalDate的使用

    LocalDate的一些使用方法 今天半天的时间都用在了LocalDate上,然后呢,也是自己的第一次写博客. 首先来看看会用上的方法吧. 两个构造器,用的是静态工厂方法 static   Local ...

  9. CCS 6新建文件自动生成注释

    对于CCS6,可以通过配置,达到新建源文件或者头文件时,自动生成适当的注释: 一.新建源文件自动生成配置. 在某个文件夹下右击选择 New - Source File. 点击 Configure,再选 ...

  10. 转载:IIS 之 连接数、并发连接数、最大并发工作线程数、队列长度、最大工作进程数

    一.IIS连接数 一般购买过虚拟主机的朋友都熟悉购买时,会限制IIS连接数,顾名思义即为IIS服务器可以同时容纳客户请求的最高连接数,准确的说应该叫“IIS限制连接数”. 客户请求的连接内容包括: [ ...