Я хочу создать программу на языке Си, которая позволяла бы мне запускать команду в терминале.
Я создал программу в сценарии оболочки, которая давала бы мне ip любого веб-сайта, который открывается в моем браузере. Этот сценарий оболочки выполняется путем ввода этой команды в терминал:
sudo tcpdump -n dst port 80 -i eth
Мой профессор сказал мне создать программу на языке C, которая открывала бы терминал и вводила эту команду, и тогда мой сценарий оболочки работал бы.
Скажите, пожалуйста, как создать такую программу.
вы можете использовать функцию system () , доступную в stdlib.h для запуска команд.
ОПИСАНИЕ
system () выполняет команду, указанную в строке, путем вызова / bin / sh -c string и возвращает ее после завершения команды. Во время выполнения команды SIGCHLD будет заблокирован, а SIGINT и SIGQUIT будут игнорироваться.
blockquote>Подробнее об этом можно прочитать здесь http://linux.about.com/library/cmd/blcmdl3_system.htm
Я собираюсь предположить, что это об использовании setuid-корневого двоичного файла для замены sudo, а не просто произвольного выполнения команды, таким образом, я собираюсь включать другие части решения.
Как вопрос безопасности, мы избегаем системы (), потому что она может быть угнана.
После компиляции этого установите получающийся двоичный файл как setuid-корень.
#include <unistd.h> #include <stdio.h> #include <sysexits.h> int main(int argc, char **argv) { if (argc > 2) { fputs("too many args\n", stderr); return EX_USAGE; } if (argc > 1 && argv[1][0] == '-') { fputs("no options allowed\n", stderr); return EX_USAGE; } if (geteuid() != 0) { fputs("not correctly installed as setuid-root\n",stderr); return EX_UNAVAILABLE; } if (setuid(0) 1) p[6] = argv[1]; /* If all goes well, execv won't return * (because this program will have been replaced by tcpdump) */ execv(p0, p); /* if we reach here then execv must have failed */ perror(p0); return EX_OSFILE; }
если Вы сохранили это как foo.c
, и хочу установленный как /usr/local/sbin/foo
, выполненный:
make foo && install -o root -m 4511 foo /usr/local/sbin/foo
Привет я запишу для Вас пример кода, объяснить это Вам и действительно надеяться, что это помогает Вам. прототип функции - что-то как:
международная система (символ константы* cmd);
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_CMN_LEN 100
int main(int argc, char *argv[])
{
char cmd[MAX_CMN_LEN] = "", **p;
if (argc < 2) /*no command specified*/
{
fprintf(stderr, "Usage: ./program_name terminal_command ...");
exit(EXIT_FAILURE);
}
else
{
strcat(cmd, argv[1]);
for (p = &argv[2]; *p; p++)
{
strcat(cmd, " ");
strcat(cmd, *p);
}
system(cmd);
}
return 0;
}
1). откройте терминал и скомпилируйте программу
2). выполните его (например, в Ubuntu)./program_name comman_name - чем-либо - что-либо
пример: локаль./a.out-a
этот пример печатает все локали, поддерживаемые моим компилятором, который является gcc.
подробнее:
p является poniter к указателю для обугливания (как argv), p = &argv[2], точки к - что-либо представляет i кошек в виде строки весь-anythings к моей строке cmd, я вышел из цикла, когда *p указывает на ПУСТОЙ взгляд на это:-> я буду использовать этот символ для высказывания, точки к (не путайте его с оператором выбора стрелки вправо).
argv [0]-> program_name
argv[1]-> command_name (на это название команды в качестве примера будет локаль, но введет команду, которую Вы хотите проверить вместо этого),
argv[2]-> - что-либо (в этом примере-a, который является всеми локалями),
argv[3]-> ПУСТОЙ УКАЗАТЕЛЬ (в этом примере, это выходит из цикла),
хорошо вот именно я думаю.