改进ls的实现(课下作业)
实现ls-a
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <dirent.h>
#include <pwd.h>
#include <utime.h>
#include <time.h>
#include <grp.h>
#ifndef FILE_MAX
#define FILE_MAX 1024
#endif
char fileName[FILE_MAX][FILENAME_MAX];
int rwxMode[] = {0,S_IRUSR, S_IWUSR, S_IXUSR, S_IRGRP, S_IWGRP, S_IXGRP, S_IROTH, S_IWOTH, S_IXOTH};
char getFileType(mode_t mode){
if(S_ISDIR(mode)) return 'd';
else if(S_ISCHR(mode)) return 'c';
else if(S_ISBLK(mode)) return 'b';
else if(S_ISFIFO(mode)) return 'f';
else if(S_ISLNK(mode)) return 'l';
else if(S_ISSOCK(mode)) return 's';
else return '-';
}
void sort(char array[][FILENAME_MAX], int n){
int i,j;
char temp[FILENAME_MAX];
for(i = n-1; i >= 0; --i)
for(j = 0; j < i; ++j)
if(strcmp(array[j], array[j+1]) > 0){
strcpy(temp, array[j]);
strcpy(array[j], array[j+1]);
strcpy(array[j+1], temp);
}
}
int main(int argc, char *argv[]){
char *dirPath;
if(argc >= 2) dirPath = argv[1];
else{
dirPath = malloc(FILENAME_MAX);
if(getcwd(dirPath, FILENAME_MAX) == NULL){
perror("getcwd returns error");
exit(EXIT_FAILURE);
}
}
DIR * dirp = opendir(dirPath);
if(dirp == NULL){
perror("opendir returns error");
exit(EXIT_FAILURE);
}
int filen = 0, i, j;
while(1){
struct dirent * fileInfo = readdir(dirp);
if(fileInfo == NULL) break;
strcpy(fileName[filen++], fileInfo->d_name);
}
sort(fileName, filen);
for(i = 0; i < filen; ++i){
struct passwd * userInfo;
struct group * groupInfo;
struct stat fileStat;
struct tm *mTime;
char fileMode[11], filePath[FILENAME_MAX];
if(dirPath[strlen(dirPath)-1] != '/')
sprintf(filePath,"%s/%s",dirPath, fileName[i]);
else sprintf(filePath, "%s%s",dirPath, fileName[i]);
if(stat(filePath, &fileStat) < 0){
perror("stat returns error");
exit(EXIT_FAILURE);
}
strcpy(fileMode, "-rwxrwxrwx");
fileMode[0] = getFileType(fileStat.st_mode);
for(j = 1; j < 10; ++j)
if(!(fileStat.st_mode & rwxMode[j])) fileMode[j] = '-';
userInfo = getpwuid(fileStat.st_uid);
groupInfo = getgrgid(fileStat.st_gid);
if(userInfo == NULL || groupInfo == NULL){
perror("getpwuid returns error");
exit(EXIT_FAILURE);
}
mTime = localtime(&fileStat.st_mtime);
printf("%s %2d %8s %8s %5d %2d月 %2d %02d:%02d %s\n",fileMode,fileStat.st_nlink,userInfo->pw_name, groupInfo->gr_name,(int)fileStat.st_size,mTime->tm_mon+1, mTime->tm_mday, mTime->tm_hour, mTime->tm_min, fileName[i]);
}
if(argc < 2) free(dirPath);
return 0;
}
ls-i
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
void show_stat_info(char *filename, struct stat *buf)
{
printf("mode\t\t:%o\n", buf->st_mode);
printf("linkers\t\t:%d\n",(int)buf->st_nlink);
printf("user\t\t:%d\n", buf->st_uid);
printf("group_id\t:%d\n", buf->st_gid);
printf("size\t\t:%d\n", (int)buf->st_size);
printf("modtime\t\t:%d\n", (int)buf->st_mtime);
printf("group_name\t:%s\n", filename);
}
int main(int argc, char **argv)
{
struct stat info;
if (argc > 1)
{
if (stat(argv[1], &info) != -1)
{
show_stat_info(argv[1], &info);
}
else
{
perror(argv[1]);
}
}
return 0;
}
ls-l
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <unistd.h>
#include <pwd.h>
#include <grp.h>
char* get_mode(mode_t m,char* str)
{
if(S_ISREG(m))
strcpy(str,"-");
else if(S_ISDIR(m))
strcpy(str,"d");
else if(S_ISCHR(m))
strcpy(str,"c");
else if(S_ISBLK(m))
strcpy(str,"b");
else if(S_ISFIFO(m))
strcpy(str,"f");
else if(S_ISLNK(m))
strcpy(str,"l");
else if(S_ISSOCK(m))
strcpy(str,"n");
strcat(str,m&S_IRUSR?"r":"-");
strcat(str,m&S_IWUSR?"w":"-");
strcat(str,m&S_IXUSR?"x":"-");
strcat(str,m&S_IRGRP?"r":"-");
strcat(str,m&S_IWGRP?"w":"-");
strcat(str,m&S_IXGRP?"x":"-");
strcat(str,m&S_IROTH?"r":"-");
strcat(str,m&S_IWOTH?"w":"-");
strcat(str,m&S_IXOTH?"x":"-");
return str;
}
int _time(int year)
{
if(year%4==0 && year%100 !=0 || year%400 == 0)
return 29;
return 28;
}
void time_ch(time_t num)
{
int year=1970;
int month =1;
int day =1;
num = num + 8*3600;
while(num >= 86400)
{
num-=86400;
day++;
if(month==1 && day == 32)
{
month++;
day =1;
}
else if(month == 2 && day ==_time(year)+1)
{
month++;
day =1;
}
else if(month == 3 && day == 32)
{
month++;
day =1;
}
else if(month == 4 && day == 31)
{
month++;
day=1;
}
else if(month == 5 && day == 32)
{
month++;
day=1;
}
else if(month == 6 && day == 31)
{
month++;
day=1;
}
else if(month == 7 && day == 32)
{
month++;
day=1;
}
else if(month == 8 && day == 32)
{
month++;
day=1;
}
else if(month == 9 && day == 31)
{
month++;
day=1;
}
else if(month == 10 && day == 32)
{
month++;
day=1;
}
else if(month == 11 && day == 31)
{
month++;
day=1;
}
else if(month == 12 && day == 32)
{
month=1;
day=1;
year++;
}
}
int hour = num/3600;
int minute =num/60 -hour*60;
printf("%2d月 %2d %2d:%2d ",month,day,hour,minute);
}
int main(int argc,char** argv,char** environ)//主函数
{
char* dir_name=NULL;
if(argc == 1)
{
dir_name=".";
}
else if(argc == 2)
{
dir_name = argv[1];
}
else
{
puts("user:ls dir");
return -1;
}
DIR* dp=opendir(dir_name);
if(NULL == dp)
{
perror("opendir");
return -1;
}
struct dirent* de=readdir(dp);
for(;de;de=readdir(dp))
{
if('.'==de->d_name[0]) continue;
struct stat s;
int ret = lstat(de->d_name,&s);
if(0 > ret)
{
perror("stat");
return -1;
}
char str[11] = {};
printf("%s ",get_mode(s.st_mode,str));
struct passwd *passwd;
passwd = getpwuid(s.st_uid);
printf ("%s ", passwd->pw_name);
struct group *group;
group = getgrgid(passwd->pw_gid);
printf ("%s ", group->gr_name);
printf("%5lu ",s.st_size);
time_ch(s.st_mtime);
printf("%s\t",de->d_name);
printf("\n");
}
closedir(dp);
}