C2018/Digest

Материал из iRunner Wiki

Введение

Лабораторная работа посвящена основам сборки программ на Linux. Нужно будет написать программу на языке C, состоящую из нескольких файлов, скомпоновать её с внешней библиотекой двумя способами (статически и динамически), организовать сборку при помощи GNU Make.

Работа выполняется на удалённом сервере, работающем под Linux, через консоль (SSH). Для подключения к серверу смотрите инструкцию.

Условие

Необходимо реализовать утилиту командной строки, которая вычисляет значение определённой хеш-функции от содержимого файлов (дайджест, контрольную сумму). В разных вариантах хеш-функции разные (MD5, SHA1, ...). Реализацию алгоритма подсчёта хеша нужно взять из указанной внешней библиотеки, не писать самостоятельно.

Если ваша программа запущена без параметров, то следует вывести краткую справку на stderr и выйти с кодом 2. Иначе каждый аргумент рассматривается как путь к файлу, для которого необходимо посчитать хеш. Результат выводится на stdout, по одной строке на каждый файл, строка содержит значение хеш-функции (в шестнадцатеричном виде) и через пробел путь к файлу. Если какой-то файл не удаётся открыть или происходит ошибка в процессе, то сообщение об этом выводится на stderr, обработка продолжается со следующего файла. Если имя файла равно -, то чтение выполняется из стандартного ввода.

При условии, что в процессе не возникало никаких ошибок, код выхода должен быть 0, иначе 1.

$ ./a.out hello.txt
18123cb2adf49f35eae45a4e305494ad hello.txt

$ cat hello.txt | ./a.out -
18123cb2adf49f35eae45a4e305494ad -

$ ./a.out - < hello.txt
18123cb2adf49f35eae45a4e305494ad -

Ваша программа должна использовать константный объём памяти независимо от размера входного файла. Читать весь файл в память нельзя, потому что объём RAM на сервере невелик, а файлы могут быть большими.

На сервере в каталоге /usr/share/c/lab-digest/ лежат файлы, на которых можно экспериментировать.

Организация кода

Несмотря на то что для решения задачи не нужно писать много кода, вам необходимо организовать программу в виде нескольких h- и c-файлов (в учебных целях). Желательно для единообразия для каждого h-файла иметь парный c-файл с тем же именем (пусть он и будет почти пустым, он хотя бы будет подключать соответствующий заголовочный файл). В обратную сторону неверно: для c-файла не обязательно должен быть свой h-файл. Имена файлов можно выбирать произвольно, чтобы они отражали смысл содержимого.

  • В некотором h-файле определите структуру, которая будет хранить значение хеш-функции.
  • В некотором c-файле реализуйте функцию вывода значения хеш-функции на стандартный вывод.
  • В некотором c-файле реализуйте функцию расчёта хеш-значения для файла по заданному пути, позаботьтесь об обработке ошибок.
  • В некотором c-файле реализуйте функцию main() и обработку аргументов командной строки.

Получится около пяти-семи разных файлов с кодом.

В результате из них вам необходимо собрать два исполняемых файла:

  1. первый динамически компонуется со всеми библиотеками;
  2. второй статически компонуется с применяемой внешней библиотекой, но динамически — с libc, linux-vdso и пр. (не полностью статическая сборка!).

Для организации сборки используйте make. Создайте Makefile.

  • Каждый c-файл должен компилироваться в отдельный o-файл, только потом должна выполняться компоновка.
  • Должна быть определена цель all для сборки сразу двух версий исполняемого файла.
  • Должна быть определена цель clean, которая удаляет собранные исполняемые файлы и промежуточные объектные файлы.
  • Организуйте процесс так, чтобы правки в заголовочных файлах корректно обрабатывались и вызывали перекомпиляцию только тех исходников, на которые они влияют прямо или косвенно. Вручную перечислять все h-файлы, от которых зависят c-файлы, нежелательно (воспользуйтесь возможностью компилятора gcc, о которой рассказывалось на лекции).

Порядок сдачи

  • На разработческом сервере код и собранные исполняемые файлы должны лежать в вашем домашнем каталоге (в подкаталоге digest). Они могут быть проверены.
  • Файлы кода и Makefile отправляются через систему AnyTask в ревью (через Review Board).
  • В сообщении укажите номер вашего варианта и приведите вывод такой команды:
$ time ./my-program /usr/share/c/lab-digest/*

Пример, как может выглядеть вывод:

$ time ./a.out /usr/share/c/lab-digest/*
e20f696e055b7c83cf04fca37cff9a66 /usr/share/c/lab-digest/BSU.png
93b885adfe0da089cdf634904fd59f71 /usr/share/c/lab-digest/empty.txt
/usr/share/c/lab-digest/inaccessible.txt: Permission denied
8ec0cf0aeddb493d227feb6adb5e6710 /usr/share/c/lab-digest/lorem.txt
06d49632c9dc9bcb62aeaef99612ba6b /usr/share/c/lab-digest/one.txt
8b9a5abedb4d4be94a517058062e5eac /usr/share/c/lab-digest/random1G.bin
fc58decb5aa53c240c8cb47fee267f1e /usr/share/c/lab-digest/zero10G.bin
bb5484aa656da76adc2b66344ba71683 /usr/share/c/lab-digest/Керниган, Ритчи — Язык программирования C.djvu

real    0m32.149s
user    0m17.584s
sys     0m2.620s

Варианты

Тот или иной вариант определяется порядковым номером N студента в ведомости группы (от 1 до 39) в системе AnyTask (первый столбец). Номер варианта вычисляется по формуле N & 0x03.

Вариант 0

Хеш-функция — MD5. Используйте библиотеку OpenSSL (пакет libssl-dev).

Вариант 1

Хеш-функция — SHA1. Используйте библиотеку OpenSSL (пакет libssl-dev).

Вариант 2

Хеш-функция — SHA256. Используйте библиотеку OpenSSL (пакет libssl-dev).

Вариант 3

Хеш-функция — CRC32. Используйте библиотеку zlib (пакет zlib1g-dev).

Подсказка

Среди стандартных утилит Linux есть программы, которые вычисляют все перечисленные хеш-суммы (md5sum, sha1sum, sha256sum, crc32). Вы можете использовать эти утилиты для самопроверки.