i have make os_error_handler
its has 4 files
src
logs
dashboard
Makefile

in src we have error_handler.c , error_handler.h, logger.c , logger.h, recovery.c, recovery.h, reporter.c, reporter.h
and one folder named "simulations" that has simulate_device_error.c, simulate_file_error.c, simulate_memory_error.c

in logs we have error_log.log

in dashboard we have app.py and template folder that has index.html and stats.html

I will provide the content inside it, i just want to know how to run this project

// File: src/error_handler.c
#include "error_handler.h"
#include "logger.h"
#include "reporter.h"
#include "recovery.h"
#include <stdio.h>
#include <stdlib.h>

// Function implementation
void handle_error(ErrorType type, const char *message, int error_code) {
// Log the error
log_error(type, message, error_code);

code
// Report the error
report_error(type, message, error_code);

// Attempt recovery
recover_from_error(type);
}

// File: src/error_handler.h
#ifndef ERROR_HANDLER_H
#define ERROR_HANDLER_H

typedef enum {
MEMORY_ERROR,
FILE_ACCESS_ERROR,
DEVICE_ERROR,
NULL_ERROR, // Added NULL_ERROR for null pointer dereference
UNKNOWN_ERROR
} ErrorType;

// Function to handle errors
void handle_error(ErrorType type, const char *message, int error_code);

#endif // ERROR_HANDLER_H

// File: src/logger.c
#include "logger.h"
#include <stdio.h>
#include <time.h>
#include <pthread.h>
#include <string.h>
#include <sys/stat.h>

#define LOG_FILE "logs/error_log.log"
#define MAX_LOG_SIZE 5242880 // 5MB

pthread_mutex_t log_mutex = PTHREAD_MUTEX_INITIALIZER;

// Function to get current timestamp
const char* current_timestamp() {
static char buffer[20];
time_t now = time(NULL);
struct tm *t = localtime(&now);
strftime(buffer, sizeof(buffer)-1, "%Y-%m-%d %H:%M:%S", t);
return buffer;
}

// Function to convert ErrorType to string
const char* error_type_to_string(ErrorType type) {
switch(type) {
case MEMORY_ERROR:
return "MEMORY_ERROR";
case FILE_ACCESS_ERROR:
return "FILE_ACCESS_ERROR";
case DEVICE_ERROR:
return "DEVICE_ERROR";
default:
return "UNKNOWN_ERROR";
}
}

// Function to rotate logs if needed
void rotate_logs_if_needed() {
struct stat st;
if (stat(LOG_FILE, &st) == 0) {
if (st.st_size >= MAX_LOG_SIZE) {
// Rename the current log file with a timestamp
char new_name[256];
time_t now = time(NULL);
struct tm *t = localtime(&now);
strftime(new_name, sizeof(new_name), "logs/error_log_%Y%m%d%H%M%S.log", t);
rename(LOG_FILE, new_name);
}
}
}

void log_error(ErrorType type, const char *message, int error_code) {
pthread_mutex_lock(&log_mutex);
rotate_logs_if_needed();
FILE *file = fopen(LOG_FILE, "a");
if (!file) {
pthread_mutex_unlock(&log_mutex);
return;
}

code
fprintf(file, "[%s] %s: %s (Error Code: %d)\n", current_timestamp(), error_type_to_string(type), message, error_code);
fclose(file);
pthread_mutex_unlock(&log_mutex);
}

// File: src/logger.h
#ifndef LOGGER_H
#define LOGGER_H

#include "error_handler.h"

void log_error(ErrorType type, const char *message, int error_code);

#endif // LOGGER_H

// File: src/recovery.c
#include "recovery.h"
#include "logger.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

// Define maximum retries and delay
#define MAX_RETRIES 3
#define RETRY_DELAY 2 // seconds

void recover_from_file_access_error(const char *filepath) {
for (int attempt = 1; attempt <= MAX_RETRIES; attempt++) {
printf("Retrying file access (Attempt %d)...\n", attempt);
FILE *file = fopen(filepath, "r");
if (file != NULL) {
printf("File accessed successfully on attempt %d.\n", attempt);
fclose(file);
return;
}
sleep(RETRY_DELAY);
}
printf("Failed to recover from FILE_ACCESS_ERROR after %d attempts.\n", MAX_RETRIES);
// Further actions, like using fallback
}

void recover_from_error(ErrorType type) {
switch(type) {
case MEMORY_ERROR:
printf("Attempting to recover from MEMORY_ERROR...\n");
// Implement recovery logic, e.g., free memory, restart process
// For demonstration, we'll simply exit
exit(EXIT_FAILURE);
break;
case FILE_ACCESS_ERROR:
printf("Attempting to recover from FILE_ACCESS_ERROR...\n");
// Example: Retry file access
recover_from_file_access_error("/path/to/nonexistent/file.txt");
break;
case DEVICE_ERROR:
printf("Attempting to recover from DEVICE_ERROR...\n");
// Attempt to reinitialize the device or switch to a backup
// For demonstration, we'll log and continue
break;
default:
printf("Unknown error type. Unable to recover.\n");
exit(EXIT_FAILURE);
}
}

// File: src/recovery.h
#ifndef RECOVERY_H
#define RECOVERY_H

#include "error_handler.h"

void recover_from_error(ErrorType type);

#endif // RECOVERY_H

// File: src/reporter.c
#include "reporter.h"
#include <stdio.h>
#include <string.h>

// Define recipient and sender email
#define RECIPIENT_EMAIL "b22cs004@iitj.ac.in"
#define SENDER_EMAIL "advaitgaur2003@gmail.com"

// Function to send email using sendmail
void send_email(const char *subject, const char *body) {
FILE *mail = popen("/usr/sbin/sendmail -t", "w");
if (mail == NULL) {
// Failed to open sendmail
return;
}

code
fprintf(mail, "To: %s\n", RECIPIENT_EMAIL);
fprintf(mail, "From: %s\n", SENDER_EMAIL);
fprintf(mail, "Subject: %s\n\n", subject);
fprintf(mail, "%s\n", body);

pclose(mail);
}

void report_error(ErrorType type, const char *message, int error_code) {
char subject[256];
char body[1024];

code
// Convert ErrorType to string
const char *type_str;
switch(type) {
case MEMORY_ERROR:
type_str = "MEMORY_ERROR";
break;
case FILE_ACCESS_ERROR:
type_str = "FILE_ACCESS_ERROR";
break;
case DEVICE_ERROR:
type_str = "DEVICE_ERROR";
break;
default:
type_str = "UNKNOWN_ERROR";
}

snprintf(subject, sizeof(subject), "OS Error Report: %s", type_str);
snprintf(body, sizeof(body), "An error of type %s occurred.\nDetails: %s\nError Code: %d",
type_str, message, error_code);

send_email(subject, body);
}

// File: src/reporter.h
#ifndef REPORTER_H
#define REPORTER_H

#include "error_handler.h"

void report_error(ErrorType type, const char *message, int error_code);

#endif // REPORTER_H

// File: src/simulations/simulate_device_error.c
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include "error_handler.h"

int main() {
printf("Simulating device access error...\n");
int fd = open("/dev/nonexistent_device", O_RDONLY);
if (fd == -1) {
printf("Device Error: %s\n", strerror(errno));
handle_error(DEVICE_ERROR, strerror(errno), errno);
return errno;
}
close(fd);
return 0;
}

// File: src/simulations/simulate_file_error.c
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include "error_handler.h"

int main() {
printf("Simulating file access error...\n");
FILE *file = fopen("/path/to/nonexistent/file.txt", "r");
if (file == NULL) {
printf("File Access Error: %s\n", strerror(errno));
handle_error(FILE_ACCESS_ERROR, strerror(errno), errno);
return errno;
}
fclose(file);
return 0;
}

// File: src/simulations/simulate_memory_error.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "error_handler.h"

// Function to simulate a memory leak
void simulate_memory_leak() {
printf("Simulating memory leak...\n");
while (1) {
malloc(1024 * 1024); // Allocate 1MB without freeing
sleep(1);
}
}

// Function to simulate a segmentation fault
void simulate_segmentation_fault() {
printf("Simulating segmentation fault...\n");
int *ptr = NULL;
*ptr = 42; // Dereference NULL pointer
}

// Function to simulate a null pointer dereference
void simulate_null_pointer_deref() {
printf("Simulating null pointer dereference...\n");
int *ptr = NULL;
if (ptr) {
*ptr = 100;
} else {
printf("Attempted to dereference a null pointer.\n");
handle_error(NULL_ERROR, "Null pointer dereference detected.", 0);
}
}

int main(int argc, char *argv[]) {
if (argc < 2) {
printf("Usage: %s <leak|segfault|null>\n", argv[0]);
return 1;
}

code
if (strcmp(argv[1], "leak") == 0) {
simulate_memory_leak();
} else if (strcmp(argv[1], "segfault") == 0) {
simulate_segmentation_fault();
} else if (strcmp(argv[1], "null") == 0) {
simulate_null_pointer_deref();
} else {
printf("Unknown simulation type.\n");
return 1;
}

return 0;
}

#!/usr/bin/env python3

import os
import smtplib
import sys
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import traceback

def debug_print_environment():
    print("Environment Variables:")
    print(f"SENDER_EMAIL: {os.getenv('SENDER_EMAIL')}")
    print(f"RECIPIENT_EMAIL: {os.getenv('RECIPIENT_EMAIL')}")
    print(f"SMTP_SERVER: {os.getenv('SMTP_SERVER')}")
    print(f"SMTP_PORT: {os.getenv('SMTP_PORT')}")
    print(f"SENDER_PASSWORD: {os.getenv('SENDER_PASSWORD')}")
    print("-----------------------------")

def debug_print_arguments():
    print(f"Script Arguments: {sys.argv}")
    print("-----------------------------")

ERROR_TYPE_MAPPING = {
    "0": "MEMORY_ERROR",
    "1": "FILE_ACCESS_ERROR",
    "2": "DEVICE_ERROR",
    "3": "NULL_ERROR",
    "4": "UNKNOWN_ERROR"
}

def send_email(subject, body):
    # Configuration from environment variables
    SMTP_SERVER = os.getenv('SMTP_SERVER', 'smtp.gmail.com')
    SMTP_PORT = int(os.getenv('SMTP_PORT', '587'))
    SENDER_EMAIL = os.getenv('SENDER_EMAIL')
    SENDER_PASSWORD = os.getenv('SENDER_PASSWORD')
    RECIPIENT_EMAIL = os.getenv('RECIPIENT_EMAIL', 'b22cs004@iitj.ac.in')

    if not SENDER_EMAIL or not SENDER_PASSWORD:
        print("Sender email or password not set in environment variables.")
        return

    # Create the email content
    message = MIMEMultipart()
    message['From'] = SENDER_EMAIL
    message['To'] = RECIPIENT_EMAIL
    message['Subject'] = subject

    message.attach(MIMEText(body, 'plain'))

    try:
        # Connect to the SMTP server
        print("Connecting to SMTP server...")
        server = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
        # server.set_debuglevel(1)  # Enable debug output
        server.starttls()
        print("Logging in to SMTP server...")
        server.login(SENDER_EMAIL, SENDER_PASSWORD)
        print("Sending email...")
        # server.send_message(message)
        server.quit()
        print("Email sent successfully.")
    except Exception as e:
        print("Failed to send email:")
        traceback.print_exc()

def main():
    debug_print_environment()
    debug_print_arguments()

    if len(sys.argv) != 4:
        print("Usage: report_error.py <ERROR_TYPE> <MESSAGE> <ERROR_CODE>")
        sys.exit(1)

    error_type_num = sys.argv[1]
    message = sys.argv[2]
    error_code = sys.argv[3]

    error_type = ERROR_TYPE_MAPPING.get(error_type_num, "UNKNOWN_ERROR")

    subject = f"OS Error Report: {error_type}"
    body = f"An error of type {error_type} occurred.\nDetails: {message}\nError Code: {error_code}"

    send_email(subject, body)

if __name__ == "__main__":
    main()


actually, log file is not updated i want that for file,device and memory loog file should be updated