C2018/Digest
Содержание
Введение
Лабораторная работа посвящена основам сборки программ на 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() и обработку аргументов командной строки.
Получится около пяти-семи разных файлов с кодом.
В результате из них вам необходимо собрать два исполняемых файла:
- первый динамически компонуется со всеми библиотеками;
- второй статически компонуется с применяемой внешней библиотекой, но динамически — с 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). Вы можете использовать эти утилиты для самопроверки.