martijnvanbrummelen / nwipe

nwipe secure disk eraser
GNU General Public License v2.0
777 stars 86 forks source link

Refactoring External Dependencies Using Unix System Calls into Libraries #622

Open Knogle opened 6 days ago

Knogle commented 6 days ago

Ahoy! As I’m spending the week in the hospital undergoing a series of tests to investigate some allergic reactions, I’ve got a bit of time and thought it might be a good opportunity to work on a project.

I’ve been considering ways to streamline dependency management for certain Linux programs that typically rely on calling external binaries and parsing their outputs. Instead of depending on these binaries, I’m thinking of refactoring them into shared or static libraries, which could simplify interactions and reduce external system calls and syntax.

I've already managed to do this with the NIST-Suite, and I believe it might also be possible for other utilities, such as hdparm, by creating a forked version that’s repurposed as a library.

Do you think this approach could be beneficial? If not, I’d appreciate any input or suggestions for other productive ideas—just looking to make good use of the week!

Knogle commented 2 days ago

Done!

HDParm Library

HDParm Logo

Table of Contents

  1. Introduction
  2. Features
  3. Installation
  4. Usage
  5. API Documentation
  6. Examples
  7. Error Handling
  8. Contributing
  9. License
  10. Acknowledgements
  11. Contact

Introduction

HDParm Library is a powerful C library designed to provide low-level access and control over hard disk drives (HDDs) and solid-state drives (SSDs) on Linux systems. Inspired by the popular hdparm utility, this library allows developers to integrate drive configuration, optimization, and management functionalities directly into their C applications.

Whether you're developing system utilities, monitoring tools, or custom drive management software, HDParm Library offers a comprehensive set of functions to interact with storage devices at a granular level.

Features

Installation

Prerequisites

Building the Library

  1. Clone the Repository:

    git clone https://github.com/yourusername/hdparm-library.git
    cd hdparm-library
  2. Compile the Library:

    As a Shared Library (libhdparm.so):

    gcc -fPIC -c hdparm_lib.c -o hdparm_lib.o
    gcc -shared -o libhdparm.so hdparm_lib.o

    As a Static Library (libhdparm.a):

    gcc -c hdparm_lib.c -o hdparm_lib.o
    ar rcs libhdparm.a hdparm_lib.o
  3. Install the Library:

    For Shared Libraries:

    sudo cp libhdparm.so /usr/local/lib/
    sudo ldconfig

    For Static Libraries:

    sudo cp libhdparm.a /usr/local/lib/
  4. Include Header Files:

    sudo cp hdparm_lib.h /usr/local/include/

Usage

Including the Library

In your C program, include the HDParm Library header:

#include "hdparm_lib.h"

Linking the Library

When compiling your program, link against the HDParm Library:

For Shared Libraries:

gcc your_program.c -L/usr/local/lib -lhdparm -o your_program

For Static Libraries:

gcc your_program.c -L/usr/local/lib -lhdparm -o your_program

Ensure that the library path (/usr/local/lib in this example) is correctly specified based on where you installed the library.

API Documentation

Initialization and Cleanup

int hdparm_init();

Initializes the HDParm Library. Call this function before using any other library functions.

int hdparm_cleanup();

Performs any necessary cleanup before the application exits.

Drive Identification

int hdparm_get_identify_data(const char *device, uint16_t *identify_data);

Retrieves the identification data from the specified drive.

int hdparm_display_identity(const uint16_t *identify_data);

Parses and displays the identification data in a human-readable format.

Drive Configuration

int hdparm_set_pio_mode(const char *device, int mode);

Sets the PIO mode of the specified drive.

int hdparm_set_dma_mode(const char *device, int mode);

Sets the DMA mode of the specified drive.

Caching Operations

int hdparm_flush_write_cache(const char *device);

Flushes the write cache of the specified drive to ensure all buffered data is written to the disk.

Security Management

int hdparm_secure_erase(const char *device, const char *password);

Performs a secure erase on the specified drive using the provided password.

Sanitization

int hdparm_sanitize_drive(const char *device, sanitize_type_t type);

Performs a sanitization operation on the specified drive.

Note: Define sanitize_type_t as per your implementation requirements.

Examples

Retrieving Drive Identification

#include <stdio.h>
#include "hdparm_lib.h"

int main() {
    int ret;
    uint16_t identify_data[256];

    ret = hdparm_init();
    if (ret != HDPARM_SUCCESS) {
        fprintf(stderr, "Failed to initialize HDParm Library.\n");
        return ret;
    }

    ret = hdparm_get_identify_data("/dev/sda", identify_data);
    if (ret != HDPARM_SUCCESS) {
        fprintf(stderr, "Failed to get identify data.\n");
        return ret;
    }

    ret = hdparm_display_identity(identify_data);
    if (ret != HDPARM_SUCCESS) {
        fprintf(stderr, "Failed to display identify data.\n");
        return ret;
    }

    ret = hdparm_cleanup();
    if (ret != HDPARM_SUCCESS) {
        fprintf(stderr, "Failed to cleanup HDParm Library.\n");
        return ret;
    }

    return 0;
}

Flushing Write Cache

#include <stdio.h>
#include "hdparm_lib.h"

int main() {
    int ret;

    ret = hdparm_init();
    if (ret != HDPARM_SUCCESS) {
        fprintf(stderr, "Failed to initialize HDParm Library.\n");
        return ret;
    }

    ret = hdparm_flush_write_cache("/dev/sda");
    if (ret != HDPARM_SUCCESS) {
        fprintf(stderr, "Failed to flush write cache.\n");
        return ret;
    }

    printf("Write cache flushed successfully.\n");

    ret = hdparm_cleanup();
    if (ret != HDPARM_SUCCESS) {
        fprintf(stderr, "Failed to cleanup HDParm Library.\n");
        return ret;
    }

    return 0;
}

Performing a Secure Erase

#include <stdio.h>
#include "hdparm_lib.h"

int main() {
    int ret;
    const char *password = "securepassword";

    ret = hdparm_init();
    if (ret != HDPARM_SUCCESS) {
        fprintf(stderr, "Failed to initialize HDParm Library.\n");
        return ret;
    }

    ret = hdparm_secure_erase("/dev/sda", password);
    if (ret != HDPARM_SUCCESS) {
        fprintf(stderr, "Failed to perform secure erase.\n");
        return ret;
    }

    printf("Secure erase completed successfully.\n");

    ret = hdparm_cleanup();
    if (ret != HDPARM_SUCCESS) {
        fprintf(stderr, "Failed to cleanup HDParm Library.\n");
        return ret;
    }

    return 0;
}

Error Handling

All functions in the HDParm Library return predefined error codes. It's essential to handle these errors gracefully in your application to ensure reliability and provide meaningful feedback to users.

Error Codes:

Usage Example:

int ret = hdparm_flush_write_cache("/dev/sda");
if (ret != HDPARM_SUCCESS) {
    switch (ret) {
        case HDPARM_ERR_OPEN:
            fprintf(stderr, "Error: Unable to open the device.\n");
            break;
        case HDPARM_ERR_IOCTL:
            fprintf(stderr, "Error: Ioctl operation failed.\n");
            break;
        // Handle other error codes as needed
        default:
            fprintf(stderr, "Error: Unknown error occurred.\n");
    }
    // Handle the error accordingly
}

Contributing

Contributions are welcome! If you'd like to improve the HDParm Library, please follow these guidelines:

  1. Fork the Repository: Create a personal copy of the repository on GitHub.

  2. Create a Branch: Make a new branch for your feature or bug fix.

    git checkout -b feature/your-feature-name
  3. Make Changes: Implement your feature or fix.

  4. Commit Changes: Write clear and concise commit messages.

    git commit -m "Add feature X that does Y"
  5. Push to Branch: Push your changes to your forked repository.

    git push origin feature/your-feature-name
  6. Open a Pull Request: Submit a pull request detailing your changes and the motivation behind them.

  7. Respond to Feedback: Collaborate with the maintainers to refine your contribution.

Guidelines:

License

This project is licensed under the MIT License. See the LICENSE file for details.

Acknowledgements


Disclaimer: This library provides low-level access to storage devices, which can lead to data loss or hardware damage if used improperly. Always ensure you have backups and understand the implications of the operations you perform.