北邮选修课unix期中实验报告

发布时间:2011-08-26 14:54:57

班级:08211312

学号:08211488

姓名:吴迪

班内序号:15


一、实验目的:

练习vi,使用UNIX的系统调用和库函数,体会UNIX文件通配符的处理方式以及命令对选项的处理方式。

编程实现程序list.c,列表普通磁盘文件(不考虑目录和设备文件等),列出文件名和文件大小。

ls命令类似,命令行参数可以有0到多个

0个参数:列出当前目录下所有文件

参数为普通文件:列出文件

参数为目录:列出目录下所有文件

实现自定义选项r,a,l,h,m以及--

r 递归方式列出子目录

a 列出文件名第一个字符为圆点的普通文件(默认情况下不列出文件名首字符为圆点的文件)

l 后跟一整数,限定文件大小的最小值(字节)

h 后跟一整数,限定文件大小的最大值(字节)

m 后跟一整数n,限定文件的最近修改时间必须在n天内

-- 显式地终止命令选项分析

二、程序说明

为了执行程序的方便,使用sudo指令将可执行文件list拷贝到/usr/bin/m_list

运行m_list即相当于运行./list

本程序实现了预定基本功能外,为方便调试,外加了-s选项:将文件夹属性也一起显示

多文件/文件夹(比如*命令)的访问使用链表struct Node动态存储对应路径位置。

另外,本程序能发现但未解决一部分新的问题,比如没有对命令-l-h-m参数不设置进行处理,而是直接报错;比如文件名如果为-s等命令形式,并未将其识别为文件名,而是判定为命令,除非前面加--(消除所有对命令的解析而是判断为文件/文件名路径参数),这一点和ls的功能保持了一致解析*遇到上述情况也是采取- -方式而非智能识别。

另外对于初始不完整的文件路径(除非在默认目录下),没有遍历去搜索该路径,而是判断为错误/不完整路径不予识别

三、程序源码

/**

*list function for unix/linux

*author: wd

*stu_id:08211488

*class_id:08211312

*final time 2011-4-28

*/

#include

#include //struct stat size requires this

#include

#include

#include

#include

//#include

#include

#include

#include

//debug message can use this print for printf or //printf

#define print //printf

//define the tab format

#define TABSPACES 9

//define print message

#define print_support_message printf("wait for higher(extern) versions to support this function!\n") //not required function

#define bool int //function para judgement -a -r (-s) -l -h -m

typedef struct Node

{

int pos;

struct Node *next;

}node;

bool is_a=0;

bool is_r=0;

bool is_l=0;

bool is_h=0;

bool is_m=0;

bool is_s=0; //s for show folders in r mode(default:not show)

int low=0; //low limit

int high=0; //up limit

int day=0; //day limit for last modify

void list(char *path);

void list_folder(char*folder_name);

int count_length(char*source)

{

char * it=source;int count = 0;

while(*it++!='\0')count++;

it--;

return count;

}

int main(int argc,char *argv[])

{

int i;int path_para;

int count_command_para=0;

int count_filename=0;

int stop=0;

node *head=(node*)malloc(sizeof(node)); //para list for filenames

node *current=head;

for(i=1;i

{

//printf("%s\n",argv[i]);

if(*(argv[i])=='-'&&!stop){

int breakp=0;

if(*(argv[i]+1)=='-'){stop=1; breakp=1;}

int j=2;char ch=*(argv[i]+1);

while(ch!='\0'&&!breakp){

count_command_para++;

switch(ch)

{

case 'a':is_a=1;break;

case 'r':is_r=1;break;

case 'l':{is_l=1;

//int low=(int)*argv[i+1];

low=atoi(argv[i+1]); i++;breakp=1;

//printf("arg=%d\n",low);

break;}

case 'h':is_h=1;

high=atoi(argv[i+1]); i++;breakp=1;

break;

case 'm':is_m=1;

day=atoi(argv[i+1]); i++;breakp=1;

break;

case 's':is_s=1; //show folders

break;

default:printf("other options!");print_support_message;break;

}

ch=*(argv[i]+(j++));

}

}

else {

count_filename++;path_para=i;

if(count_filename==1){

head->pos=i;

head->next=NULL;

}

else{

node *temp;

temp=(node*)malloc(sizeof(node));

temp->pos=i;

temp->next=NULL;

current->next=temp;

current=current->next;

}

printf("%s\n",argv[i]);

// printf("path_para==%d\n",path_para);

/*if(count_filename>1)

{

printf("Too many filenames or foldernames!");

print_support_message;

return 0;

}*/

}

}

char *path;

if(count_filename==0) {

char buf[80];

getcwd(buf,sizeof(buf));

//printf("%s\n",buf);

path = buf;

list(path);

free(head);

}

else{

current=head;

while(current!=NULL){

head=current;

path_para=current->pos;

path = argv[path_para]; //main file or folder path

//printf("%s\n",path);

list(path);

current=current->next;

free(head);

}

}

return 0;

}

void list_folder(char*folder_name)

{

DIR * dir;

struct dirent* ptr;

char *source;//folder_name;

source = (char*)malloc(sizeof(count_length(folder_name)));

memcpy(source,folder_name,count_length(folder_name));

source[count_length(folder_name)]='\0';

dir = opendir(folder_name);

if(chdir(source)==0){

//printf("change success!\n");

}

else{

//perror("change failed!\n");

}

if(dir==NULL){

printf("No such folder found!\n");

}

else{

while((ptr = readdir(dir))!=NULL)

{

//struct dirent* temp_ptr;

//first char of ptr->d_name is an integer 46

//which means '.'

char*path=ptr->d_name;

struct stat st;

int ret=stat(path,&st);

off_t size=st.st_size;

time_t timer=time(NULL);

//struct tm *time=localtime(&timer);

time_t betime=timer-st.st_mtime;

time_t time_limit;

time_limit=day*3600*24;

if(ret==-1)

{

printf("path error!\n");

}else{}

if(is_r){

if(ptr->d_type==4&&*(ptr->d_name)!=46){//not include file or dot from results

if(is_s==1){

if(is_l==1&&(int)size

else if(is_h==1&&(int)size>high) ;

else if(is_m==1&&(int)time_limit

else {

printf("name: %s type: %s location at %s\n",ptr->d_name,ptr->d_type==8?"file":"folder",source);

}

}

char* sub_folder_name=ptr->d_name;

list_folder(sub_folder_name);

}

}

if(ptr->d_type==8){

if((*(ptr->d_name)!=46)||(is_a&&*(ptr->d_name)==46))//second part is dot file

{

if(is_l==1&&(int)size

else if(is_h==1&&(int)size>high) ;

else if(is_m==1&&(int)time_limit

else {

printf("name: %s type: %s length %d location at %s\n",ptr->d_name,ptr->d_type==8?"file":"folder",(int)size,source);

//printf("last modified time: %d\n",(int)betime);

}

}

}

}

char old_path[80];

char new_path[80];

getcwd(old_path,sizeof(old_path));

char*begin=old_path;

char*end=strrchr(old_path,'/');

int len=end-begin;

memcpy(new_path,old_path,len);

new_path[len]='\0';

// printf("len=%d",len);

// printf("new =%s\n old =%s\n",new_path,old_path);

if(chdir(new_path)==0){

// printf("back success!\n");

}

else{

// perror("back failed!\n");

}

getcwd(old_path,sizeof(old_path));

// printf("current=%s\n",old_path);

closedir(dir);}

}

void list(char *path)

{

struct stat st;

int ret=stat(path,&st);

if(ret==-1)

{

printf("Such a path not found!\n");

}

else{

if(S_ISDIR(st.st_mode)){

list_folder(path);

}

else{

off_t size=st.st_size;

printf("name: %s type: file length %d \n",path,(int)size);//show file info

}

}

}

四、运行测试

1 a r m 1 Music

2 a r m 3 Music

3 Music

4 l 100 h 5000 m 1 /bin /etc

5 ar l 1000 m 2

6 -- -as

7 -- -r

8 -- *

9 -- -a –s -r

10 *.c l 100 h 10000

实验总结

本次实验练习使用了vi编辑器编写代码,熟悉了命令模式和编辑模式的转换过程和编辑特性。list函数功能实现过程中遇到过许多问题,通过对这些问题的研究和解决的过程温故了unixc语言程序的编写。程序在不断修改过程中初步完成了所有题设对应功能。尽管又发现了新的问题而且最终没有编写对应的解决代码,但是能够提出这些问题和对应的解决方案。本次实验的个人基本目标已经达到。

北邮选修课unix期中实验报告

相关推荐