/*
 * $Header: /datum01/src/continuity/src/xfer.c,v 1.19.2.3 2002/09/16 15:15:31
 * aleigh Exp $
 */

/*
 * Copyright (c) 1994, 2004 Alex Leigh, All Rights Reserved
 * 
 * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF ALEX LEIGH The copyright
 * notice above does not evidence any actual or intended publication of such
 * source code.
 * 
 * Disclosure, copying, distribution, or transmission of this code without
 * express permission is prohibited.
 */

#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <uuid/uuid.h>

#include "continuity.h"

#define CHUNK_SZ 10240

int xfrFfile(netTconn *conn, const char *path) {
    struct stat s;
    int ret;

    ret = stat(path, &s);

    if (ret == -1)
        return -1;

    ret = xfrFmmap(conn, path, &s);
    return ret;

}

int xfrFis_extant(char *path) {
    int ret;

    struct stat s;

    ret = stat(path, &s);

    if (ret == 0)
        return 1;

    return 0;
}

/*
 * -> mmap contains the mapping -> len the length
 */
int xfrFmmap(netTconn *conn, const char *fname,struct stat *sb) {
    char *map;
    off_t written = 0, ret;

    map = (char *) mmcFmap(fname, (struct stat *) sb, NULL);

    if (map == NULL)
        return STATUS_ERROR;

    while (1) {
        if ((sb->st_size - written) > CHUNK_SZ) {
            ret = netFconn_write(conn, map + written, CHUNK_SZ);
        } else {
            ret =
                    netFconn_write(conn, map + written,
                                   (sb->st_size - written));
        }

        if (ret == -1) {
            return STATUS_ERROR;
        } else {
            written += ret;
            if (written >= sb->st_size)
                break;
        }
    }
    return written;
}

int xfrFmemory(netTconn *conn, char *p, size_t len) {
    size_t written = 0;
    char *wp;
    ssize_t ret;

    wp = p;

    while (1) {
        if (len - written < CHUNK_SZ) {
            ret = netFconn_write(conn, wp, len - written);

            if (ret == -1) {
                return written;
            }
            written += ret;
            wp += ret;
        } else {
            ret = netFconn_write(conn, wp, CHUNK_SZ);

            if (ret == -1) {
                return written;
            }
            written += ret;
            wp += ret;
        }
        if (written == len)
            break;
    }

    return written;
}
