Task 407: .MODULES File Format
Task 407: .MODULES File Format
File Format Specifications for the .MODULES File Format
Based on my search, the .MODULES (typically .modules in lowercase) file format is not a binary or structured data format with a formal specification like ZIP or PNG. Instead, it is a plain text shell script used in Linux distributions (such as Oracle Linux, Red Hat Enterprise Linux, and derivatives like AlmaLinux or CentOS) to automatically load kernel modules at boot time. These files are placed in the /etc/sysconfig/modules/ directory, must have executable permissions (usually 755), and are owned by root. The content is a simple shell script that typically includes a shebang line and commands to load kernel modules using modprobe, often with conditional checks to avoid reloading already loaded modules.
There is no official "file format" specification beyond being a valid shell script. The file is executed during the boot process by the system (e.g., via init scripts or systemd). Examples include scripts for loading modules like uinput or kvm. In some other contexts, .modules files can be plain text configuration files for build systems (e.g., in software like Gramps), but the primary association is with Linux kernel module loading.
- List of all the properties of this file format intrinsic to its file system.
Since the .MODULES file is a standard file in the file system (plain text shell script), its intrinsic properties are the metadata provided by the file system (e.g., in POSIX systems like Linux). These are obtained via the stat system call or equivalent. The complete list is:
- Device ID (st_dev): The ID of the device containing the file.
- Inode number (st_ino): The file's inode number.
- File mode (st_mode): The file's permissions and type (e.g., S_IFREG for regular file, plus octal permissions like 0755).
- Number of hard links (st_nlink): The number of hard links to the file.
- User ID of owner (st_uid): The UID of the file owner (typically 0 for root).
- Group ID of owner (st_gid): The GID of the file owner (typically 0 for root).
- Device ID for special files (st_rdev): The device ID if the file is a special device file (usually 0 for regular files).
- File size (st_size): The size of the file in bytes.
- Block size (st_blksize): The preferred block size for efficient I/O operations.
- Number of blocks allocated (st_blocks): The number of 512-byte blocks allocated to the file.
- Last access time (st_atime): The time of last access (in seconds since epoch).
- Last modification time (st_mtime): The time of last content modification (in seconds since epoch).
- Last status change time (st_ctime): The time of last metadata change (in seconds since epoch).
These properties are common to all files in the file system and are not unique to .MODULES, but they are the "intrinsic" ones as per the query.
- Two direct download links for files of format .MODULES.
- https://raw.githubusercontent.com/gramps-project/gramps/master/mac/gramps.modules (A configuration file from the Gramps genealogy software project.)
- https://git.almalinux.org/rpms/qemu-kvm/raw/commit/903966e69c12395482a079f21839959de391e40f/kvm.modules (A kernel module loading script from the AlmaLinux qemu-kvm package.)
- Ghost blog embedded HTML JavaScript that allows a user to drag n drop a file of format .MODULES and it will dump to screen all these properties.
(Note: "Ghost blog embedded" likely means embeddable HTML/JS for a blog post. In a browser, we can access limited file properties via the File API: name, size, type, lastModified. Full FS properties like inode or UID are not accessible for security reasons. The code below dumps what is available and reads the file content as text since .MODULES is plain text. It checks if the file ends with .modules or .MODULES.)
- Python class that can open any file of format .MODULES and decode read and write and print to console all the properties from the above list.
(Note: Python uses os.stat to read FS properties. "Decode" is not applicable since it's plain text, so the class reads the content as text. The write method creates or overwrites a file with example content for a .MODULES file.)
import os
import time
class ModulesFileHandler:
def __init__(self, filepath):
self.filepath = filepath
if not self.filepath.lower().endswith('.modules'):
raise ValueError("File must have .MODULES extension")
def read_and_print_properties(self):
stat = os.stat(self.filepath)
print("Device ID:", stat.st_dev)
print("Inode number:", stat.st_ino)
print("File mode:", oct(stat.st_mode))
print("Number of hard links:", stat.st_nlink)
print("User ID of owner:", stat.st_uid)
print("Group ID of owner:", stat.st_gid)
print("Device ID for special files:", stat.st_rdev)
print("File size:", stat.st_size)
print("Block size:", stat.st_blksize)
print("Number of blocks:", stat.st_blocks)
print("Last access time:", time.ctime(stat.st_atime))
print("Last modification time:", time.ctime(stat.st_mtime))
print("Last status change time:", time.ctime(stat.st_ctime))
# Read content (decode as text)
with open(self.filepath, 'r') as f:
content = f.read()
print("\nFile Content:\n", content)
def write_example_file(self, module_name='example'):
content = f"""#!/bin/sh
if [ ! -c /dev/{module_name} ] ; then
exec /sbin/modprobe {module_name} >/dev/null 2>&1
fi
"""
with open(self.filepath, 'w') as f:
f.write(content)
os.chmod(self.filepath, 0o755) # Set executable permissions
print(f"Written example .MODULES file to {self.filepath}")
# Example usage:
# handler = ModulesFileHandler('example.modules')
# handler.write_example_file('uinput')
# handler.read_and_print_properties()
- Java class that can open any file of format .MODULES and decode read and write and print to console all the properties from the above list.
(Note: Java uses java.nio.file.Files and BasicFileAttributeView for FS properties. Write method creates or overwrites with example content.)
import java.io.*;
import java.nio.file.*;
import java.nio.file.attribute.*;
import java.time.Instant;
public class ModulesFileHandler {
private final Path path;
public ModulesFileHandler(String filepath) {
this.path = Paths.get(filepath);
if (!filepath.toLowerCase().endsWith(".modules")) {
throw new IllegalArgumentException("File must have .MODULES extension");
}
}
public void readAndPrintProperties() throws IOException {
BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class);
System.out.println("Device ID: " + attrs.fileKey()); // Approximation for device/inode
System.out.println("File size: " + attrs.size());
System.out.println("Is regular file: " + attrs.isRegularFile());
System.out.println("Last access time: " + Instant.ofEpochMilli(attrs.lastAccessTime().toMillis()));
System.out.println("Last modification time: " + Instant.ofEpochMilli(attrs.lastModifiedTime().toMillis()));
System.out.println("Creation time: " + Instant.ofEpochMilli(attrs.creationTime().toMillis()));
PosixFileAttributes posixAttrs = Files.readAttributes(path, PosixFileAttributes.class);
System.out.println("File mode: " + posixAttrs.permissions());
System.out.println("Number of hard links: not directly available in Java BasicAttributes");
System.out.println("User ID of owner: " + posixAttrs.owner().getName());
System.out.println("Group ID of owner: " + posixAttrs.group().getName());
// Read content (decode as text)
String content = new String(Files.readAllBytes(path));
System.out.println("\nFile Content:\n" + content);
}
public void writeExampleFile(String moduleName) throws IOException {
String content = "#!/bin/sh\n" +
"if [ ! -c /dev/" + moduleName + " ] ; then\n" +
" exec /sbin/modprobe " + moduleName + " >/dev/null 2>&1\n" +
"fi\n";
Files.write(path, content.getBytes());
Files.setPosixFilePermissions(path, PosixFilePermissions.fromString("rwxr-xr-x"));
System.out.println("Written example .MODULES file to " + path);
}
// Example usage:
// public static void main(String[] args) throws IOException {
// ModulesFileHandler handler = new ModulesFileHandler("example.modules");
// handler.writeExampleFile("uinput");
// handler.readAndPrintProperties();
// }
}
- Javascript class that can open any file of format .MODULES and decode read and write and print to console all the properties from the above list.
(Note: Assuming Node.js, as browser JS can't open arbitrary files. Uses fs.statSync for properties. Write method creates or overwrites with example content.)
const fs = require('fs');
const path = require('path');
class ModulesFileHandler {
constructor(filepath) {
this.filepath = filepath;
if (!path.extname(this.filepath).toLowerCase() === '.modules') {
throw new Error('File must have .MODULES extension');
}
}
readAndPrintProperties() {
const stat = fs.statSync(this.filepath);
console.log('Device ID:', stat.dev);
console.log('Inode number:', stat.ino);
console.log('File mode:', stat.mode.toString(8));
console.log('Number of hard links:', stat.nlink);
console.log('User ID of owner:', stat.uid);
console.log('Group ID of owner:', stat.gid);
console.log('Device ID for special files:', stat.rdev);
console.log('File size:', stat.size);
console.log('Block size:', stat.blksize);
console.log('Number of blocks:', stat.blocks);
console.log('Last access time:', stat.atime);
console.log('Last modification time:', stat.mtime);
console.log('Last status change time:', stat.ctime);
// Read content (decode as text)
const content = fs.readFileSync(this.filepath, 'utf8');
console.log('\nFile Content:\n', content);
}
writeExampleFile(moduleName = 'example') {
const content = `#!/bin/sh\nif [ ! -c /dev/${moduleName} ] ; then\n exec /sbin/modprobe ${moduleName} >/dev/null 2>&1\nfi\n`;
fs.writeFileSync(this.filepath, content);
fs.chmodSync(this.filepath, 0o755);
console.log(`Written example .MODULES file to ${this.filepath}`);
}
}
// Example usage:
// const handler = new ModulesFileHandler('example.modules');
// handler.writeExampleFile('uinput');
// handler.readAndPrintProperties();
- C class that can open any file of format .MODULES and decode read and write and print to console all the properties from the above list.
(Note: C does not have classes, so this is implemented as a struct with functions. Uses stat for properties. Write function creates or overwrites with example content.)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
struct ModulesFileHandler {
char *filepath;
};
struct ModulesFileHandler* create_handler(const char *filepath) {
if (strstr(filepath, ".modules") == NULL && strstr(filepath, ".MODULES") == NULL) {
fprintf(stderr, "File must have .MODULES extension\n");
exit(1);
}
struct ModulesFileHandler *handler = malloc(sizeof(struct ModulesFileHandler));
handler->filepath = strdup(filepath);
return handler;
}
void destroy_handler(struct ModulesFileHandler *handler) {
free(handler->filepath);
free(handler);
}
void read_and_print_properties(struct ModulesFileHandler *handler) {
struct stat st;
if (stat(handler->filepath, &st) != 0) {
perror("stat");
return;
}
printf("Device ID: %ld\n", (long)st.st_dev);
printf("Inode number: %ld\n", (long)st.st_ino);
printf("File mode: %o\n", st.st_mode);
printf("Number of hard links: %ld\n", (long)st.st_nlink);
printf("User ID of owner: %d\n", st.st_uid);
printf("Group ID of owner: %d\n", st.st_gid);
printf("Device ID for special files: %ld\n", (long)st.st_rdev);
printf("File size: %ld\n", (long)st.st_size);
printf("Block size: %ld\n", (long)st.st_blksize);
printf("Number of blocks: %ld\n", (long)st.st_blocks);
printf("Last access time: %s", ctime(&st.st_atime));
printf("Last modification time: %s", ctime(&st.st_mtime));
printf("Last status change time: %s", ctime(&st.st_ctime));
// Read content (decode as text)
FILE *f = fopen(handler->filepath, "r");
if (f) {
printf("\nFile Content:\n");
char buf[1024];
while (fgets(buf, sizeof(buf), f)) {
printf("%s", buf);
}
fclose(f);
}
}
void write_example_file(struct ModulesFileHandler *handler, const char *module_name) {
FILE *f = fopen(handler->filepath, "w");
if (!f) {
perror("fopen");
return;
}
fprintf(f, "#!/bin/sh\nif [ ! -c /dev/%s ] ; then\n exec /sbin/modprobe %s >/dev/null 2>&1\nfi\n", module_name, module_name);
fclose(f);
chmod(handler->filepath, 0755);
printf("Written example .MODULES file to %s\n", handler->filepath);
}
// Example usage:
// int main() {
// struct ModulesFileHandler *handler = create_handler("example.modules");
// write_example_file(handler, "uinput");
// read_and_print_properties(handler);
// destroy_handler(handler);
// return 0;
// }