Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
методичка ПО ОСРВ заочники.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
8.72 Mб
Скачать

3.6.8. Объединение всего вместе: Is2.C

Мы проверили каждый компонент в выводе Is -1. Для каждого из них мы знаем, что означа­ет каждое поле и как можно преобразовать значение поля в форму, наиболее понятную для пользовательского восприятия. В результате программа ls2.c будет такой:

/* Is2.c

* цель - вывод списка содержимого каталога или каталогов

* при отсутствии аргументов используется., в противном случае

* используется список имен файлов через список аргументов

* замечание - использует stat, pwd.h и grp.h

ж BUG: попробуйте Is2 /tmp

*/

#include <stdio.h>

«include <sys/types.h>

«include <dirent.h>

«include <sys/stat.h>

voiddo_ls(char[]); void dostatfchar *);

void showfilejnfofchar * struct stat *);

void mode_tOiletters(int, char []);

char *uidJo_name(uid_t);

char *gid_to_name(gid_t);

main(int ac, char *av[ ])

{

if(ac==l)

dojsf'.");

else

while (--ac){

prinrf("%s:\n", *++av);

do_ls(*av);

}

}

void do ls(char dirname[ ])

/*

* перечисляет файлы в каталоге с именем dirname

/*

{

DIR *dir_ptr; Г каталог */

struct dirent *direntp; /* какая запись */

if ((dir_ptr = opendir(dirname)) == NULL)

fprintf(stderr,"ls1: cannot open %s\n", dirname);

else

{

while ((direntp = readdir(dir_ptr)) != NULL)

dostat(direntp- >d_name);

closedir(dir ptr);

}

}

void dostatfchar *filename)

{

struct stat info;

if (stat(filename, &info) == -1) /* неудача у stat */

perror(filename); /* посмотреть почему */

else /* иначе показать информациюshow_ file_ info(filename, &info);

}

void show_file_jnfo(char *filename, struct stat *info p)

/*

* выводит информацию о 'filename'. Эта информация записана в структуре

*info_p

*/

{

char *uid_to_name(), *ctime(), *gid_to^name(), *filemode();

void mode_to_letters();

charmodestr[11];

mode_toJetters(info_p- >st_mode, modestr);

prinrf("%s", modestr);

printf("%4d", (int) info_p->st_nlink);

printf("%-8s", uid_to_name(info_p->st_uid));

printf("%-8s", gid_to_name(info_p->st_gid));

printf("%8ld", (long)info_p->st_size);

printf("%.12s", 4+ctime(&info_p->st_mtime));

printf("%s\n", filename);

}

/*

* utility functions

*/

/*

* В этой функции извлекается значение mode и формируется символьный массив.

* В символьный массив помещается значение типа файла и

* девять символов для представления прав доступа.

* ЗАМЕЧАНИЕ: Коды setuid, setgid sticky

* не рассматриваются

*/

void modejojettersfint mode, char str[ ])

{

strcpy(str,"--------------"); /* по умолчанию отсутствие прав */

if(SJSDIR(mode))str[0] = 'd'; /* каталог?*/

if (SJSCHR(mode)) str[0] = 'с'; /* символьные устройства */

if (SJSBLK(mode)) str[0] = 'b'; /* блочное устройство 7

if (mode & S IRUSR) str[1] = 'r'; /* 3 разряда для собственника */

if(mode&SJWUSR)str[2] = 'w';

if(mode&SJXUSR)str[3] = 'x';

if (mode & SJRGRP) str[4] = 'r'; /* 3 разряда для группы */

if(mode&SJWGRP)str[5] = 'w';

if (mode & SJXGRP) str[6] = Y;

if (mode & SJROTH) str[7] = 'r'; /* 3 разряда для остальных */

if(mode&S_IWOTH)str[8] = W;

if(mode&SJXOTH)str[9] = 'x';

}

«include <pwd.h>

char *uid to name(uid t uid)

/*

* возвращается указатель на пользовательское имя, соотнесенное

ж идентификатору uid, используется getpw()

*/

{

struct passwd *getpwuid(), *pw_ptr;

static char numstr[10];

if ((pw_ptr = getpwuid(uid)) == NULL){

sprintf(numstr,"% d", uid);

return numstr;

}

else

return pw ptr->pw name;

}

«include <grp.h>

char *gid to name(gid t gid)

/*

* возвращается указатель на имя группы, используется getgrgid(3)

*/

{

struct group *getgrgid(), *grp_ptr;

static char numstr[10];

if ((grp_ptr = getgrgid(gid)) == NULL){

sprintf(numstr,"% d", gid);

return numstr;

}

else

return grp ptr- >gr name;

}

И вот теперь запустим нашу программу и получим также для сравнения стандартный вывод:

drwxrwxr-x

drwxrwxr-x

-rw-rw-r--

-rwxrwxr-x

-rw-rw-r--

-rw-r--r--

-rw-r--r--

-rw-rw-r-

drwxrwxr-x

drwxrwxr-x

4 bruce

5 bruce 1 bruce

1 bruce

2 bruce 1 bruce 1 bruce

1 bruce

2 bruce 2 bruce

bruce

bruce

users

users

users

users

users

users

users

users

1024 Aug \1024 Aug 30720 Aug 37351 Aug

345 Jul

723 Aug

3045 Feb 27521 Aug 1024 Aug

1024 Aug

218:18.

218:14..

1 12:05 s.tar 1 12:13 taill 29 11:05 Makefile

1 14:26 Is 1.с

15 03:51 Is2.c 1 12:14 chap03

1 12:14oldsrc

1 12:15 docs

-rwxrwxr-x

1 bruce

bruce

37048 Aug

1 14:26 Is1

•rw-r-r--

1 bruce

support

946 Feb

1817:15stat1.c

-rwxrwxr-x

2 bruce

bruce

42295 Aug

2 18:18 Is2

-rw-r-r-

1 bruce

support

191 Feb

9 21:01 statdemo.c

-rw-r-r-

1 bruce

users

1416Aug

1 12:05 tain, с

$ ls-I

total 189

-rw-rw-r--

2 bruce

users

345 Jul

29 11:05 Makefile

-rw-rw-r--

1 bruce

users

27521 Aug

1 12:14chap03

drwxrwxr-x

2 bruce

users

1024 Aug

1 12:15 docs

-rwxrwxr-x

1 bruce

bruce

37048 Aug

1 14:26 Isl

-rw-r--r-

1 bruce

users

723 Aug

1 14:26 Isl. с .

-rwxrwxr-x

2 bruce

bruce

42295 Aug

2 18:18 Is2

-rw-r-r--

1 bruce

users

3045 Feb

15 03:51 Is2.c

drwxrwxr-x

2 bruce

users

1024 Aug

1 12:14old_src

-rw-rw-r--

1 bruce

users

30720 Aug

1 12:05 s.tar

-rw-r--r-

1 bruce

support

946 Feb

18 17:15 statl.c

-rw-r--r--

1 bruce

support

191 Feb

9 1998 statdemo.c

-rwxrwxr-x

1 bruce

users

37351 Aug

1 12:13 tain

-rw-r--r-

1 bruce

users

1416 Aug

1 12:05 taiH.с

$

Чего мы достигли?

Программа Is2 отображает информацию о файлах в стандарте вывода команды Is -I. Вывод выглядит хорошо. Он происходит поколонно, производится преобразование из внутренне­го представления разрядов доступа и числовых значений идентификатора в читабельные строки.

Но программа все же нуждается в доработке. В реальной версии в самой первой строке вывода печатается строка total. Зачем нужна эта строка? Кроме того, в нашей программе все еще нет сортировки имен файлов, не работает опция - а, не производится упорядоче­ния имен файлов по колонкам, программа рассматривает каждый аргумент при обраще­нии к ней в качестве имени каталога.

В программе Is2 есть еще более серьезные проблемы. Она не будет корректно выдавать ин­формацию о файлах, которые находятся в других каталогах. Для рассмотрения проблемы попытайтесь выполнить команду Is2 /tmp. Следует решить эту проблему, что вы должны сделать в качестве упражнения.