/* 
 * FILE:   pathsearch.c
 * AUTHOR: Alan Shutko <ats@hubert.wustl.edu>
 *
 * ID: $Id: pathsearch.c,v 1.3 1996/12/17 05:58:12 ats Exp $
 *
 * Functions:
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include <limits.h>
#include <unistd.h>
#include <ftw.h>
#include "int-fiction.h"
#include "ats.h"

#ifndef DEFAULT_IF_PATH
#define DEFAULT_IF_PATH "/usr/games//:/usr/lib/games//:."
#endif /* DEFAULT_IF_PATH */

const char *basename(const char *filename);

extern gameptr games;
char *fullpath = NULL;


/*
 * Called by ftw in pathsearch_valid_games to mark valid games.
 */

int check_valid(const char* pathname, struct stat *statptr, int type)
{
    switch(type)
    {
        case FTW_F:
            mark_valid( pathname );
            break;
        case FTW_D:
            break;
        case FTW_DNR:
            break;
        case FTW_NS:
            break;
        default:
            break;
    }
    return(0);
}


/*
 * Marks the valid field of a named game.  Also puts the full pathname
 * instead of the partial pathname from the game list.
 */

int mark_valid(const char *pathname)
{
    int ret = 0;
    gameptr *tmpgame = &games;

    for (tmpgame = &games; *tmpgame; tmpgame = &(*tmpgame)->next)
    {
        if ((strcmp( basename(pathname), (*tmpgame)->File) == 0) &&
            (!(*tmpgame)->valid))
        {
            (*tmpgame)->valid = 1;
            strcpy((*tmpgame)->File, pathname);
            ret = 1;
            break;
        }
    }
    return(ret);
}

/*
 * Check the path for all valid games.  (Valid games are games
 * listed in the game list which exist in the path.)  Mark the games
 * as valid and record their full path.
 */

int pathsearch_valid_games(void)
{
        char *path, *tmp;
    static char *filename = NULL;
    
    if (!filename)
        if (!(filename = pathalloc(NULL)))
            error_system(ERR_QUIT, "cannot allocate pathname");

    if (!fullpath)
        if (!(fullpath = pathalloc(NULL)))
            error_system(ERR_QUIT, "cannot allocate pathname");
    

    if (!(tmp = getenv("IF_PATH")))
    {
        if (!(path = malloc(strlen(DEFAULT_IF_PATH)+1)))
            error_system(ERR_QUIT, "failed to allocate memory for path");
        strcpy(path, DEFAULT_IF_PATH);
    }
    else
    {
        path = malloc(strlen(tmp)+1);
        strcpy(path, tmp);
    }

    for (tmp = strtok(path, ":"); tmp; tmp = strtok(NULL, ":"))
    {
        strcpy(filename, tmp);
        
        if (strcmp(filename+strlen(filename) - 2, "//")) /* Not Recursive */
        {
            if (filename[strlen(filename) - 1] != '/')
            {
                filename[strlen(filename)+1] = '\0';
                filename[strlen(filename)] = '/';
            }

            simple_check_dir(filename);
        }
        else
        {
            filename[strlen(filename) - 2] = '\0';
            recurse_check_dir(filename);
        }
    }
    return(0);
}

/*
 * Check a directory for games, non-recursively
 */

int simple_check_dir(const char *filename)
{
    static char *fullpath =NULL;
    struct dirent *dirp;
    DIR *dp;
    char *ptr;
    
    if (!fullpath)
        if (!(fullpath = pathalloc(NULL)))
            error_system(ERR_QUIT, "cannot allocate pathname");

    strcpy(fullpath, filename);
    if ( (dp = opendir(fullpath)) == NULL)
        return(0);              /* can't read directory */

    ptr = fullpath + strlen(fullpath);
    *ptr++ = '/';
    *ptr = 0;

    while ( (dirp = readdir(dp)) != NULL)
    {
        if (strcmp(dirp->d_name, ".") == 0 ||
            strcmp(dirp->d_name, "..") == 0)
            continue;
        strcpy(ptr, dirp->d_name); /* append name after slash */
        
        mark_valid(fullpath);
    }
    if (closedir(dp) < 0)
        error_system(ERR_RETURN, "Can't close directory %s", fullpath);

    return(0);
}

/*
 * Check a directory for valid games, recursively
 */

int recurse_check_dir(const char *filename)
{
    return( ftw(filename, check_valid, 10) );
}

const char *basename(const char *filename)
{
    const char *p;

    p = filename + strlen(filename);

    while((p >= filename) && (*p != '/'))
        p--;
    return(p+1);
}
