If we are handling a file, then we proceed to io_read_file(), which has changed slightly from the previous version:
...
// 1) odd inodes are GIF files, even inodes are text files
if (ocb -> base.attr -> base.inode & 1) {
if (!ocb -> output) {
...
// 2) allocate the input and output structures as before
...
sprintf (string, "%0*d", optd, ocb -> base.attr -> count++);
(*ocb -> render) (string, input, optx, opty);
ocb -> size = ocb -> base.attr -> base.nbytes = encode_image (
input, optx, opty, ocb -> output);
// 3) note the changes to write_file()
if (optS) {
write_file (optS, ocb -> base.attr -> base.inode / 2 - 1,
ocb -> base.attr -> count);
}
}
} else { // 4) even, so must be the text attribute
int tmp; // limited scope
ocb -> base.attr -> count =
attr_gif [ocb -> base.attr -> base.inode / 2 - 1].count;
tmp = sprintf (string, "%0*d\n", optd, ocb -> base.attr -> count);
if (ocb -> output) {
free (ocb -> output);
}
ocb -> output = strdup (string);
ocb -> size = tmp;
}
Notice a few things:
What might appear to be "clever" use of inodes is in fact standard programming practice. When you think about it, a disk-based filesystem makes use of the inodes in a similar manner; it uses them to find the disk blocks on the media.