/*
 * libkarma/mountSearch.c
 *
 * Copyright (c) Enrique Vidal <evidal@iti.upv.es> 2006
 *
 * You may distribute and modify this program under the terms of 
 * the GNU GPL, version 2 or later.
 *
 */

#include <stdio.h>
#include <stdlib.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

#include "lkarma.h"
#include "util.h"

#define PROC_MOUNTS "/proc/mounts"

int fd, ret;
char *ini, *fin;

static char *read_whole_file(char *filename)
{
    int len = BUFSIZ;
    char *ptr = NULL;
    FILE *fp = fopen(filename, "rb");
    int size;

    if (!fp)
        goto err;

    ptr = malloc(len);
    if (!ptr)
        goto err;

    while ((size = fread(ptr + len - BUFSIZ, 1, BUFSIZ, fp)) == BUFSIZ) {
        ptr = realloc(ptr, len + BUFSIZ);
        if (!ptr)
            goto err;

        len += BUFSIZ;
    }
    *(ptr + len - BUFSIZ + size) = 0;
    fclose(fp);
err:
    return ptr;
}

int lk_mountSearch_discover(char **device, char **mountPoint)
{
    char *buf, *dev, *mountp, *aux;
    int len, pos, kfd, found=0;

    buf = read_whole_file(PROC_MOUNTS);
    if (!buf)
    {
        lk_errors_set(E_MFINDERR);
        return -1;
    }
/* fprintf(stderr, "%s\n\n", buf); */

    ini = buf;
    pos = 0;
    while ((fin = strstr(ini, "\n"))) {
        if(fin) {
            *fin = '\0';
/*          fprintf(stderr, "%s\n", ini); */
            if(strstr(ini, "omfs")) {
                dev = ini;
                aux = strstr(dev, " ");
                *aux = '\0';
                ini = aux + 1;
                if((mountp = strstr(ini, "/"))) {
                    aux = strstr(mountp, " ");
                    *aux = '\0';
                    if(((*device     = strdup(dev))    == NULL) ||
                       ((*mountPoint = strdup(mountp)) == NULL)) {
                        lk_errors_set(E_NOMOUNT);
                        free(buf);
                        return -1;
                    }
/*                  fprintf(stderr, "%s %s\n", *device, *mountPoint); */
                  
                    if(lk_is_karma_mountpoint(*mountPoint) != 0) {
                        free(*mountPoint);
                        free(*device);
                        *mountPoint=NULL;
                        lk_errors_set(E_NOMOUNT);
                        free(buf);
                        return -1;
                    }
                    found++;
                }
            }
        }
        ini = fin + 1;
    }
    free(buf);

    if(found != 1) {
        lk_errors_set((found==0)?E_NOMOUNT:E_MANYMOUNT);
        return -found-1;
    }
    return 0;
}
