L1: Ἡ Βιβλιοθήκη τῆς Ἀλεξάνδρειας #
It is the third century BC. Callimachus of Cyrene (Καλλίμαχος ὁ Κυρηναῖος) has just completed his famous Pinakes (Πίνακες), a vast catalogue of hundreds of thousands of scrolls in the Library of Alexandria, in 120 volumes. It took an enormous amount of work, but as you might expect, such a large catalogue is still inconvenient to use. Callimachus is undeterred and is already thinking about another improvement to the Library’s resource indexing. For this, he plans to use the latest achievement of Hellenic technology: a computer running Λίνουξ operating system.
Callimachus will enter information about the scrolls into the computer. Your task is to write a program that runs on Λίνουξ and uses the ΠΟΣΙΞ API to create the appropriate indexes.
Remember to release all unused resources (memory and file descriptors), check system function errors, and follow good programming practices.
Stages:
At this stage, the program takes one argument: the path to a file containing metadata for a book in the library. The metadata uses a simple format: each line contains a
key:valuepair. You may assume there are no extra:characters on a line, but you must handle other invalid input. Read the file and print the values of theauthor,title, andgenrefields, in that order. If a field is missing, printmissing!for it. For example, given a file containing:uthor:Plutarch latin_title:De fluviorum et montium nominibus et de iis, quae in illis inveniuntur title:Περὶ ποταμῶν καὶ ὀρῶν ἐπωνυμίας genre:geography incipit:When Chrysippe, through the anger of Aphrodite had fallen into a yearning for Hydaspesthe program should print:
author: missing! title: Περὶ ποταμῶν καὶ ὀρῶν ἐπωνυμίας genre: geography(The first line contains a typo, so the program does not find the
authorfield.)Hint: The standard library provides many useful functions for this kind of parsing, such as
getline,strchr,strcmp, andstrdup.Hint 2: We will need this functionality again later, though not immediately, so it is best to put it in a separate function.
Callimachus’s database mirrors the physical structure of the Great Library in its directory tree. Nested directories represent the building’s wings, rooms, shelves, racks, chests... At the end of this hierarchy are regular files whose names reflect the titles written on the outside of the scrolls (which need not match the actual book titles in the metadata).
Modify the program so it no longer takes arguments. When run, it recursively searches the
librarydirectory. All regular files represent books. Create anindexdirectory in the program’s current directory (report an error if it already exists). Inside it, create a directory namedby-visible-title. Put relative symbolic links there to all the books (files) in the library, using their names but without their nested directory structure. If any name is repeated, report an error.Create two new indexes alongside
by-visible-title.The
by-titleindex is similar to the one from the previous stage, but uses thetitlemetadata field as the filename. If the field is missing, skip the file. If the title is longer than 64 bytes, truncate it to that length.The
by-genreindex places books in subdirectories of the formindex/by-genre/<genre>, where<genre>is the value of thegenremetadata field. Use the book’s metadata title as the filename, as above. Truncate thegenrevalue to 64 bytes if necessary.
The final index feature is checking that no books are missing. Another programmer has already created a file containing a list of all the books in binary format. At this stage, if provided, the program’s first argument is the path to this database file. Read its contents and check that no books are missing. The database format is as follows: it contains some number of entries, each consisting of 4 bytes representing the file size (
unsigned int) and the first 64 bytes of the title (from the metadata). If the title is shorter than 64 bytes, the field is padded with zeros, so each entry is always 68 bytes; the number of entries can be determined from the file size. Scan the library. For every missing book, printBook "<title>" is missing; if the file size does not match, printBook "<title>" size mismatch (<expected size> vs <file size>). Usereadvto read the database. Use theby-titleindex to check whether books are missing.The starter files contain two example databases. The first,
database_correct, contains all books in thelibrarydirectory. The second,database_missing, contains additional books, so the check should report an error.Hint: To ensure the string is always null-terminated, you can use a 65-character array in the structure representing a single book and set the last character to zero. This way, even if the title has been truncated to the full 64 bytes, the string will still be null-terminated after reading it.