當前位置:編程學習大全網 - 編程語言 - linux c編程

linux c編程

/*

Name: list.c

Author: guozan _SCS_BUPT

Mail: guozan523@foxmail.com

Date: 2010/4/6

實驗目的:練習vi,使用UNIX的系統調用和庫函數,體會UNIX文件通配符的處理方式以及命令對選項的處理方式。

編程實現程序list.c,列表普通磁盤文件(不考慮目錄和設備文件等),列出文件名和文件大小。

與ls命令類似,命令行參數可以有0到多個

0個參數:列出當前目錄下所有文件

參數為普通文件:列出文件

參數為目錄:列出目錄下所有文件

實現自定義選項r,a,l,h,m以及--

r 遞歸方式列出子目錄

a 列出文件名第壹個字符為圓點的普通文件(默認情況下不列出文件名首字符為圓點的文件)

l 後跟壹整數,限定文件大小的最小值(字節)

h 後跟壹整數,限定文件大小的最大值(字節)

m 後跟壹整數n,限定文件的最近修改時間必須在n天內

-- 顯式地終止命令選項分析

*/

#include <sys/stat.h>

#include <sys/types.h>

#include <dirent.h>

#include <unistd.h>

#include <stdio.h>

#include <string.h>

/*

slective options about ls

rflag is about recursive

aflag is about ones with . infront

lflag is about the minimum size

hflag is about the maximum size

mflag is about the modified time

*/

int rflag, aflag, lflag, hflag, mflag;

long modified_time; //the last time file be modified, days ago

off_t lower_size; //file's minimum size

off_t upper_size; //file's maximum size

/*

set the flags, thus the ls option

*/

void getoptions(int argc, char *argv[])

{

char ch;

//clear, all unseted

rflag = 0; aflag = 0; lflag = 0; hflag = 0; mflag = 0;

//use getopt to get the options, want to know more, call man

//the last one or after -- was set in argv[optind]

while ((ch = getopt(argc, argv, "ral:h:m:")) != -1) {

switch (ch) {

case 'r': rflag = 1; break;

case 'a': aflag = 1; break;

case 'l': lflag = 1; lower_size = atol(optarg); break;

case 'h': hflag = 1; upper_size = atol(optarg); break;

case 'm': mflag = 1; modified_time = atol(optarg); break; //get days

case '?': printf("Unknown option: %c\n", (char)optopt); break;

default : printf("Step into default\n"); break;

}

}

}

/*

the function to list things in path

*/

int ls(char *path)

{

struct stat st; //for check this is a directory or file

char temp[100]; //if path is null, it is used to get current directory

// get the path

if (path == NULL || path[0] == '-') {

path = temp;

getcwd(path, 100);

}

/* open the inode of file */

if (lstat(path, &st)) {

fprintf(stderr, "Error: %s not exist.\n", path);

return (-1);

}

/* judge whether the file is a file or a directory */

if (S_ISDIR(st.st_mode)) {

ls_dir(path);

}

else if (S_ISREG(st.st_mode)) {

print(path);

}

else {

printf("Not ordinary file, wouldn't be listed.\n");

}

return 0;

}

/*

list dirs, may recursively or not, depending on rflag

one thing is sure that it will list directories and files first,

then consider the things in the directories

*/

int ls_dir(char *path)

{

DIR *dp = NULL;

struct dirent *dirp = NULL;

if (path[0] != '.' || (path[0] == '.' && aflag == 1)) {

printf("\n%s:\n****************************************\n", path);

/* open the directory */

if ((dp = opendir(path)) == NULL) {

fprintf(stderr, "Error: can't open directory %s!\n", path);

return (-1);

}

chdir(path);

/* list all the things in directory */

while ((dirp = readdir(dp)) != NULL) {

print(dirp->d_name);

}

/* recursively ls dirs, after ls things together,

it's time to list things in children directory */

if (rflag == 1) {

rewinddir(dp); //reset dp

while ((dirp = readdir(dp)) != NULL) {

if (strcmp(dirp->d_name, ".") == 0

|| strcmp(dirp->d_name, "..") == 0) { //no current and parent directory

continue;

}

ls_dir_r(dirp->d_name); //only list directories, judged inside the function

}

}

/* close the directory */

if (closedir(dp)) {

fprintf(stderr, "Error: can't close the directory %s!\n", path);

return -1;

}

chdir("..");

}

return 0;

}

/*

list directories recursively,

only directories, nomatter what path you put in

*/

int ls_dir_r(char *path)

{

struct stat st;

/* open the inode of file */

if (lstat(path, &st)) {

fprintf(stderr, "Error: %s not exist.\n", path);

return (-1);

}

/* only ls directories */

if (S_ISDIR(st.st_mode)) {

ls_dir(path);

}

}

/*

print the filetype/size/name on the screen

*/

int print(char *path)

{

struct stat st;

time_t tp;

char *filename = NULL;

//get current time

time(&tp);

if (lstat(path, &st)) {

fprintf(stderr, "Error: %s can't be opened.\n", path);

return (-1);

}

/* get file name */

if ((filename = strrchr(path, '/')) != NULL) {

filename++;

}

else {

filename = path;

}

/* judge whether to list the file */

if ((S_ISDIR(st.st_mode)|| S_ISREG(st.st_mode)) //only directories and normal files

&& (lflag == 0 || (lflag == 1 && (st.st_size >= lower_size))) //the min size

&& (hflag == 0 || (hflag == 1 && (st.st_size <= upper_size))) //the max size

&& (mflag == 0 || (mflag == 1 && ((tp - st.st_mtime) <= modified_time * 24 * 60 * 60))) //modified time

&& (aflag == 1 || (aflag == 0 && filename[0] != '.')) //file with a '.' infront

) {

printf("%s\t%10ld\t%s\n", (S_ISDIR(st.st_mode) ? "DIR": "FILE"), st.st_size, filename);

}

return 0;

}

/*

The main function

*/

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

{

getoptions(argc, argv);

ls(argv[optind]);

return 0;

}

  • 上一篇:計算機專業的學生怎樣選擇自己的發展方向比較合適?
  • 下一篇:培訓機構改造小學編程教學。
  • copyright 2024編程學習大全網