#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#define MAX_ITEMS 100
#define MAX_STRING_LENGTH 100
#define MAX_CUSTOM_DIR_PATH (MAX_STRING_LENGTH * 3) // Increased size to accommodate longer paths
struct Item {
int id;
char name[MAX_STRING_LENGTH];
char model[MAX_STRING_LENGTH];
char config[MAX_STRING_LENGTH];
char hash[MAX_STRING_LENGTH];
};
void createCustomDirectory(const char *directoryName) {
char documentsPath[MAX_STRING_LENGTH * 2];
const char *homeDirectory = getenv("HOME");
if (homeDirectory == NULL)
{
fprintf(stderr, "ERROR: Unable to get user's home directory\n");
exit(1);
}
snprintf(documentsPath, sizeof(documentsPath), "%s/Documents", homeDirectory);
char customDirPath[MAX_CUSTOM_DIR_PATH];
snprintf(customDirPath, MAX_CUSTOM_DIR_PATH, "%s/%s", documentsPath, directoryName);
char *dir = customDirPath;
while ((dir = strchr(dir + 1, '/')) != NULL)
{
*dir = '\0';
if (access(customDirPath, F_OK) == -1)
{
if (mkdir(customDirPath, 0700) == -1)
{
fprintf(stderr, "ERROR: Unable to create custom directory\n");
exit(1);
}
}
*dir = '/';
}
if (access(customDirPath, F_OK) == -1)
{
if (mkdir(customDirPath, 0700) == -1)
{
fprintf(stderr, "ERROR: Unable to create custom directory\n");
exit(1);
}
}
}
void displayMenu()
{
printf("----------------------Menu----------------------\n");
printf("1. Add Item\n");
printf("2. View Items\n");
printf("3. Search Item by ID\n");
printf("4. Load Items from File\n");
printf("5. Save Items to .snet File\n");
printf("6. Exit Program\n");
printf("------------------------------------------------\n");
printf("\n");
}
void addItem(struct Item *items, int *itemCount)
{
if (*itemCount >= MAX_ITEMS)
{
printf("ERROR: Maximum item count reached.\n");
return;
}
struct Item item;
printf("Enter Item ID: ");
scanf("%d", &item.id);
printf("Enter Item Name: ");
scanf("%s", item.name);
printf("Enter Item Model: ");
scanf("%s", item.model);
printf("Enter Item Config: ");
scanf("%s", item.config);
printf("Enter Item Hash: ");
scanf("%s", item.hash);
items[*itemCount] = item;
(*itemCount)++;
printf("SUCCESS: Item added.\n");
}
int compareItems(const void *a, const void *b)
{
return ((struct Item *)a)->id - ((struct Item *)b)->id;
}
void viewItems(const struct Item *items, int itemCount)
{
if (itemCount == 0)
{
printf("ERROR: No items to display\n");
return;
}
struct Item sortedItems[itemCount];
memcpy(sortedItems, items, itemCount * sizeof(struct Item));
qsort(sortedItems, itemCount, sizeof(struct Item), compareItems);
printf("Items:\n");
printf("ID\tName\tModel\tConfig\tHash\n");
for (int i = 0; i < itemCount; i++) {
printf("%d\t%s\t%s\t%s\t%s\n", sortedItems[i].id, sortedItems[i].name, sortedItems[i].model,
sortedItems[i].config, sortedItems[i].hash);
}
}
void searchItemByID(const struct Item *items, int itemCount, int searchID)
{
for (int i = 0; i < itemCount; i++)
{
if (items[i].id == searchID)
{
printf("SUCCESS: Item Found\n");
printf("ID\tName\tModel\tConfig\tHash\n");
printf("%d\t%s\t%s\t%s\t%s\n", items[i].id, items[i].name, items[i].model, items[i].config,
items[i].hash);
return;
}
}
printf("ERROR: Item with ID %d not found\n", searchID);
}
void saveItemsToFile(const struct Item *items, int itemCount, const char *fileName)
{
FILE *file = fopen(fileName, "w");
if (file == NULL)
{
fprintf(stderr, "ERROR: Unable to open file for writing: %s\n", fileName);
return;
}
for (int i = 0; i < itemCount; i++)
{
fprintf(file, "%d\t%s\t%s\t%s\t%s\n", items[i].id, items[i].name, items[i].model, items[i].config,
items[i].hash);
}
fclose(file);
printf("SUCCESS: Items have been saved to %s\n", fileName);
}
// Function to append items from a .snet file to the existing array.
void loadItemsFromFile(struct Item *items, int *itemCount, const char *fileName)
{
FILE *file = fopen(fileName, "r");
if (file == NULL)
{
fprintf(stderr, "ERROR: Unable to open file for reading: %s\n", fileName);
return;
}
int loadedItemCount = 0; // Track the number of items loaded from the file.
while (!feof(file) && loadedItemCount < MAX_ITEMS)
{
struct Item item;
// Read item data from file.
if (fscanf(file, "%d %99s %99s %99s %99s", &item.id, item.name, item.model, item.config, item.hash) == 5)
{
if (*itemCount < MAX_ITEMS)
{
items[*itemCount] = item; // Append the loaded item to the existing items array.
(*itemCount)++;
loadedItemCount++;
} else {
printf("WARNING: Maximum item count reached. Loaded items beyond the limit will be discarded.\n");
break;
}
}
}
fclose(file);
printf("SUCCESS: %d items have been loaded from %s\n", loadedItemCount, fileName);
}
int main() {
const char *customDirectoryName = "Documents/Projects/bcs1_c_l_hello_world_1";
createCustomDirectory(customDirectoryName);
struct Item items[MAX_ITEMS];
int itemCount = 0;
int choice;
char fileName[MAX_STRING_LENGTH + 5]; // +5 for ".snet"
// Prompt the user for the .snet file to load at the start.
printf("Enter .snet file name to load (or press Enter to skip): ");
if (fgets(fileName, sizeof(fileName), stdin))
{
fileName[strcspn(fileName, "\n")] = '\0'; // Remove trailing newline if present
// Load items from the specified .snet file.
loadItemsFromFile(items, &itemCount, fileName);
}
do {
displayMenu();
printf("Enter choice: ");
scanf("%d", &choice);
switch (choice)
{
case 1:
addItem(items, &itemCount);
break;
case 2:
viewItems(items, itemCount);
break;
case 3:
printf("Enter ID to search: ");
int searchID;
scanf("%d", &searchID);
searchItemByID(items, itemCount, searchID);
break;
case 4:
printf("Enter file name to load: ");
scanf("%s", fileName);
loadItemsFromFile(items, &itemCount, fileName);
break;
case 5:
printf("Enter file name to save (.snet extension will be added): ");
scanf("%s", fileName);
strcat(fileName, ".snet");
saveItemsToFile(items, itemCount, fileName);
break;
case 6:
printf("Exiting program...\n");
break;
default:
printf("ERROR: Invalid choice\n");
break;
}
} while (choice != 6); // Keep the menu running until choice is 6 (Exit).
return 0; // Properly exit the program.
}