LINUX.ORG.RU

Ненормальная работа функции system()


0

0

В одной из прог мне необходимо было использовать функцию system() для передачи командному интерпретатору команды ls -l имя_файла, но почему- то вывод этой команды отображается раньше, чем текст, который по идее должнен быть перед её выводом. Код фрагмента проги, выполняющего вызов ls -l:

{
      printf("You don't have rights to read this file.\n"\
      "Rights for this file:");
      char b[]="ls -l ";
      system(strncat(b,argv[1],strlen(argv[1])));
      printf("\n");
      return 0;
   }
вывод проги:
[alex@95-65-17-135 ~]$ ./cloncat hreni 
You don't have rights to read this file.
----------. 1 alex alex 0 Май 16 22:39 hreni
Rights for this file:
[alex@95-65-17-135 ~]$ 
Спасибо всем, кто поможет понять, почему прога так работает и как это исправить.

★★★

Последнее исправление: Dorif (всего исправлений: 1)

Ответ на: комментарий от tim239

Ок. как её написать, чтоб не было возможности эксплойт написать? Что изменить?

Dorif ★★★
() автор топика
Ответ на: комментарий от Deleted

Так примерно?

{
		printf("You don't have rights to read this file.\n"
		"Rights for this file:\n");
		//fflush(stdout);
		setbuf(stdout, NULL);
		char b[7+strlen(argv[1])];
		strcpy(b, "ls -l "); 
		system(strcat(b,argv[1]));
		return 1;
	}

Dorif ★★★
() автор топика

Ура! Переполнения не возникает! Всё работает даже без fflush() или setbuf(). Отдельное спасибо mironov_ivan.)))

Dorif ★★★
() автор топика
Ответ на: комментарий от Dorif

Да, хотел потом удалить это сообщение но не вышло. А вариант с

$ touch a\;date 
$./cloncat a* 
на итоговой проге работает?

Потому что у меня:

$ cat a\;date 
ddq
dasdsa
$ chmod 000 a\;date 
$ ./test2 a*
You don't have rights to read this file.
Rights for this file:
ls: невозможно получить доступ к a: Нет такого файла или каталога
Срд Май 19 16:47:00 MSD 2010

tim239 ★★
()
Ответ на: комментарий от tim239
alex@95-65-17-135 ~]$ touch a
[alex@95-65-17-135 ~]$ chmod 000 a
[alex@95-65-17-135 ~]$ ./cloncat a*
You don't have rights to read this file.
Rights for this file:
----------. 1 alex alex 0 Май 19 16:07 a
[alex@95-65-17-135 ~]$ 

Работает, как видишь. Правда если указать аргументом a* допустим, то она выводит только содержимое первого файла с названием на эту букву. Пока не знаю просто как можно обработать эту ситуацию и отобразить ВСЕ файлы, имя которых начинается с этой буквы.

Dorif ★★★
() автор топика
Ответ на: комментарий от Dorif

Это не то. Файл должен называться «a;date». Создать его можно с помощью

$ touch a\;date
- обрати внимание на обратную косую черту перед точкой с запятой.

tim239 ★★
()
Ответ на: комментарий от Dorif

Если логика программы та же, то тут ты имеешь право на чтение файла и system() не выполняется. А вот если сделать до этого chmod 000 a\;date , то есть мнение что в system передастся строка «ls -l a;date» и date выполнится.

tim239 ★★
()
Ответ на: комментарий от tim239

есть такое. А как можно ещё вывести права на файл в том виде, как их выводит ls? Если юзать stat(), то просто выдаёт 0ю А нужно знать и права других юзверей на файл. Есть какие- то идеи?

Dorif ★★★
() автор топика
Ответ на: комментарий от Dorif

В man 2 stat есть пример, если его скомпилировать, то:

$./stat a\;date 
File type:                regular file
I-node number:            5139
Mode:                     100000 (octal)
Link count:               1
Ownership:                UID=1000   GID=1000
Preferred I/O block size: 4096 bytes
File size:                11 bytes
Blocks allocated:         8
Last status change:       Wed May 19 16:46:43 2010
Last file access:         Wed May 19 16:45:35 2010
Last file modification:   Wed May 19 16:45:33 2010
Все, что показывает ls, там есть.

tim239 ★★
()
Ответ на: комментарий от tim239

Ок, спасибо. Не знал. что маны есть не только по утилитам. но и по функциям С...

Dorif ★★★
() автор топика
Ответ на: комментарий от tim239

У меня эта команда ничего не выдала.( Linux Fedora 12

Dorif ★★★
() автор топика
Ответ на: комментарий от tim239

Написал.

else if(access(argv[1],4)==-1){
		stat(argv[1],&buf);
		printf("You don't have rights to read this file.\n"
		"Rights for this file:\nAccess mode: %o\nUID of owner: %d\n"
		"GID of owner: %d\nLast access time:%ld\nLast status change time:%ld\n"
		"Last change time:%ld\n",buf.st_mode,buf.st_uid,buf.st_gid,buf.st_atime,buf.st_mtime,buf.st_ctime);
		return 1;
	}
Но одно «но»: время выводит в секундах с 1 яваря 1970.
[alex@95-65-17-135 ~]$ ./cloncat hreni 
You don't have rights to read this file.
Rights for this file:
Access mode: 100000
UID of owner: 500
GID of owner: 500
Last access time:1274038768
Last status change time:1274038767
Last change time:1274038771
Как ты делал даты удобочитаемыми?

Dorif ★★★
() автор топика
Ответ на: комментарий от Dorif

Вот пример из нового man'а по stat. Он написан очень хорошо, обрати внимание на мелочи типа fprintf(stderr, «Usage: %s <pathname>\n», argv[0]); и не мелочи типа проверки кода возврата функции stat.

#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
	struct stat sb;

	if (argc != 2) {
		fprintf(stderr, "Usage: %s <pathname>\n", argv[0]);
		exit(EXIT_FAILURE);
	}

	if (stat(argv[1], &sb) == -1) {
		perror("stat");
		exit(EXIT_FAILURE);
	}

	printf("File type:                ");

	switch (sb.st_mode & S_IFMT) {
	case S_IFBLK:
		printf("block device\n");
		break;
	case S_IFCHR:
		printf("character device\n");
		break;
	case S_IFDIR:
		printf("directory\n");
		break;
	case S_IFIFO:
		printf("FIFO/pipe\n");
		break;
	case S_IFLNK:
		printf("symlink\n");
		break;
	case S_IFREG:
		printf("regular file\n");
		break;
	case S_IFSOCK:
		printf("socket\n");
		break;
	default:
		printf("unknown?\n");
		break;
	}

	printf("I-node number:            %ld\n", (long) sb.st_ino);

	printf("Mode:                     %lo (octal)\n", (unsigned long) sb.st_mode);

	printf("Link count:               %ld\n", (long) sb.st_nlink);
	printf("Ownership:                UID=%ld   GID=%ld\n", (long) sb.st_uid, (long) sb.st_gid);

	printf("Preferred I/O block size: %ld bytes\n", (long) sb.st_blksize);
	printf("File size:                %lld bytes\n", (long long) sb.st_size);
	printf("Blocks allocated:         %lld\n", (long long) sb.st_blocks);

	printf("Last status change:       %s", ctime(&sb.st_ctime));
	printf("Last file access:         %s", ctime(&sb.st_atime));
	printf("Last file modification:   %s", ctime(&sb.st_mtime));

	exit(EXIT_SUCCESS);
}

tim239 ★★
()
Ответ на: комментарий от tim239

Хороший пример, спасибо. Не всё пока пригодилось, но, думаю ещё пригодится. А этот ман из какого дистра? В Федоре 13 будет?

Dorif ★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.