HuntnGather – Rev 1

Subversion Repositories:
Rev:
///////////////////////////////////////////////////////////////////////////
//    Copyright (C) 2021 Wizardry and Steamworks - License: MIT          //
///////////////////////////////////////////////////////////////////////////

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <ctype.h>

#include <proto/dos.h>
#include <proto/exec.h>

#if defined ___AmigaOS___
#include "getopt.h"
#endif

#if !defined TRUE
#define TRUE 1;
#endif

#if !defined FALSE
#define FALSE 0;
#endif

/*************************************************************************/
/*        Version string used for querrying the program version.         */
/*************************************************************************/
TEXT version_string[] =
        "\0$VER: Hunt 1.2 "__DATE__" by Wizardry and Steamworks";

int run = TRUE;

void SignalHandler(int sig) {
        // Toggle the run flag to stop execution.
        run = FALSE;
}

/*
        *
        * Counts the lines in a database file "dbFile".
        */
int CountDatabaseLines(char *dbFile) {
        FILE *fp;
        int lines;
        char c;

        if((fp = fopen(dbFile, "r")) == NULL) {
                fprintf(stderr, "Unable to open gather database for reading.\n");
                fclose(fp);
                return 0;
        }

        lines = 0;
        while(fscanf(fp, "%c", &c) == 1) {
                switch(c) {
                        case '\n':
                                ++lines;
                                break;
                }
        }

        fclose(fp);

        return lines;
}


/*
        * Convert string to uppercase.
        */
char *strupr(char *str) {
        char *up;
        int i;

        up = (char *) malloc((strlen(str) + 1) * sizeof(char));
        sprintf(up, "%s", str);

        i = strlen(up);
        while(--i > -1) {
                up[i] = toupper(up[i]);
        }

        return up;
}

/*
        *
        * Search the database for a matching string.
        */
void SearchDatabase(char *dbFile, char* string, int lines) {
        FILE *fp;
        char *name;
        char *path;
        char c;
        int i;
        int side;
        int match;
        int total;

        if((fp = fopen(dbFile, "r")) == NULL) {
                fprintf(stderr, "Unable to open gather database for reading.\n");
                return;
        }

        name = (char *) malloc(sizeof(char));
        path = (char *) malloc(sizeof(char));
        i = 0;
        side = 0;
        match = FALSE;
        total = 0;
        while(run && fscanf(fp, "%c", &c) == 1) {
#if defined ___AmigaOS___
                // Check if CTRL+C was pressed and abort the program.
                if(SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
                        break;
                }
#endif

                switch(c) {
                        case '\n':
                                ++total;
                                if(match) {
                                        fprintf(stdout, "%s\n", path);
                                        match = FALSE;
                                }
                                if(name != NULL) {
                                        free(name);
                                        name = (char *) malloc(sizeof(char));
                                }
                                --side;
                                i = 0;
                                break;
                        case '\t':
                                // Case insensitive match.
                                if(strstr(strupr(name), strupr(string)) != NULL) {
                                        match = TRUE;
                                }
                                if(path != NULL) {
                                        free(path);
                                        path = (char *) malloc(sizeof(char));
                                }
                                ++side;
                                i = 0;
                                break;
                        default:
                                switch(side) {
                                        case 0:
                                                name = (char *) realloc(name, (i + 1 + 1) * sizeof(char));
                                                name[i] = c;
                                                name[i + 1] = '\0';
                                                break;
                                        case 1:
                                                path = (char *) realloc(path, (i + 1 + 1) * sizeof(char));
                                                path[i] = c;
                                                path[i + 1] = '\0';
                                                break;
                                        default:
                                                fprintf(stderr, "Database corrupted.\n");
                                                break;
                                }
                                ++i;
                                break;
                }
        }

        fclose(fp);
}

void Hunt(char *dbFile, char *needle) {
        int lines;

        lines = CountDatabaseLines(dbFile);

        // Search the database for the matching string.
        SearchDatabase(dbFile, needle, lines);
}

int main(int argc, char **argv) {
        int option;

        // Bind handler to SIGINT.
        signal(SIGINT, SignalHandler);

        while((option = getopt(argc, argv, "h")) != -1) {
                switch(option) {
                        case 'h':
                                fprintf(stdout, "SYNTAX: %s STRING", argv[0]);
                                break;
                        case '?':
                                fprintf(stderr, "Invalid option %c.\n", optopt);
                                fprintf(stdout, "SYNTAX: %s STRING\n", argv[0]);
                                return 1;
                }
        }

        if(optind > argc) {
                fprintf(stdout, "SYNTAX: %s [-q] STRING\n", argv[0]);
                return 1;
        }

        Hunt("S:gather.db", argv[1]);

   return 0;
}