155682Smarkm/*
2233294Sstas * Copyright (c) 1997 - 2004 Kungliga Tekniska H��gskolan
3178825Sdfr * (Royal Institute of Technology, Stockholm, Sweden).
4178825Sdfr * All rights reserved.
555682Smarkm *
6178825Sdfr * Redistribution and use in source and binary forms, with or without
7178825Sdfr * modification, are permitted provided that the following conditions
8178825Sdfr * are met:
955682Smarkm *
10178825Sdfr * 1. Redistributions of source code must retain the above copyright
11178825Sdfr *    notice, this list of conditions and the following disclaimer.
1255682Smarkm *
13178825Sdfr * 2. Redistributions in binary form must reproduce the above copyright
14178825Sdfr *    notice, this list of conditions and the following disclaimer in the
15178825Sdfr *    documentation and/or other materials provided with the distribution.
1655682Smarkm *
17178825Sdfr * 3. Neither the name of the Institute nor the names of its contributors
18178825Sdfr *    may be used to endorse or promote products derived from this software
19178825Sdfr *    without specific prior written permission.
2055682Smarkm *
21178825Sdfr * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22178825Sdfr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23178825Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24178825Sdfr * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25178825Sdfr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26178825Sdfr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27178825Sdfr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28178825Sdfr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29178825Sdfr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30178825Sdfr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31178825Sdfr * SUCH DAMAGE.
3255682Smarkm */
3355682Smarkm
3455682Smarkm#include "krb5_locl.h"
35102644Snectar#include "store-int.h"
3655682Smarkm
37178825Sdfrtypedef struct fd_storage {
3855682Smarkm    int fd;
39178825Sdfr} fd_storage;
4055682Smarkm
4155682Smarkm#define FD(S) (((fd_storage*)(S)->data)->fd)
4255682Smarkm
4355682Smarkmstatic ssize_t
44178825Sdfrfd_fetch(krb5_storage * sp, void *data, size_t size)
4555682Smarkm{
4672445Sassar    return net_read(FD(sp), data, size);
4755682Smarkm}
4855682Smarkm
4955682Smarkmstatic ssize_t
50178825Sdfrfd_store(krb5_storage * sp, const void *data, size_t size)
5155682Smarkm{
5272445Sassar    return net_write(FD(sp), data, size);
5355682Smarkm}
5455682Smarkm
5555682Smarkmstatic off_t
56178825Sdfrfd_seek(krb5_storage * sp, off_t offset, int whence)
5755682Smarkm{
5855682Smarkm    return lseek(FD(sp), offset, whence);
5955682Smarkm}
6055682Smarkm
61233294Sstasstatic int
62233294Sstasfd_trunc(krb5_storage * sp, off_t offset)
63233294Sstas{
64233294Sstas    if (ftruncate(FD(sp), offset) == -1)
65233294Sstas	return errno;
66233294Sstas    return 0;
67233294Sstas}
68233294Sstas
69178825Sdfrstatic void
70178825Sdfrfd_free(krb5_storage * sp)
71178825Sdfr{
72178825Sdfr    close(FD(sp));
73178825Sdfr}
74178825Sdfr
75233294Sstas/**
76233294Sstas *
77233294Sstas *
78233294Sstas * @return A krb5_storage on success, or NULL on out of memory error.
79233294Sstas *
80233294Sstas * @ingroup krb5_storage
81233294Sstas *
82233294Sstas * @sa krb5_storage_emem()
83233294Sstas * @sa krb5_storage_from_mem()
84233294Sstas * @sa krb5_storage_from_readonly_mem()
85233294Sstas * @sa krb5_storage_from_data()
86233294Sstas */
87233294Sstas
88233294SstasKRB5_LIB_FUNCTION krb5_storage * KRB5_LIB_CALL
89233294Sstaskrb5_storage_from_fd(krb5_socket_t fd_in)
9055682Smarkm{
91178825Sdfr    krb5_storage *sp;
92233294Sstas    int fd;
9390926Snectar
94233294Sstas#ifdef SOCKET_IS_NOT_AN_FD
95233294Sstas#ifdef _MSC_VER
96233294Sstas    if (_get_osfhandle(fd_in) != -1) {
97233294Sstas	fd = dup(fd_in);
98233294Sstas    } else {
99233294Sstas	fd = _open_osfhandle(fd_in, 0);
100233294Sstas    }
101233294Sstas#else
102233294Sstas#error Dont know how to deal with fd that may or may not be a socket.
103233294Sstas#endif
104233294Sstas#else  /* SOCKET_IS_NOT_AN_FD */
105233294Sstas    fd = dup(fd_in);
106233294Sstas#endif
107233294Sstas
108178825Sdfr    if (fd < 0)
10990926Snectar	return NULL;
11090926Snectar
111178825Sdfr    sp = malloc(sizeof(krb5_storage));
112178825Sdfr    if (sp == NULL) {
113178825Sdfr	close(fd);
114178825Sdfr	return NULL;
115178825Sdfr    }
116178825Sdfr
11755682Smarkm    sp->data = malloc(sizeof(fd_storage));
11890926Snectar    if (sp->data == NULL) {
119178825Sdfr	close(fd);
12090926Snectar	free(sp);
12190926Snectar	return NULL;
12290926Snectar    }
12355682Smarkm    sp->flags = 0;
124102644Snectar    sp->eof_code = HEIM_ERR_EOF;
12555682Smarkm    FD(sp) = fd;
12655682Smarkm    sp->fetch = fd_fetch;
12755682Smarkm    sp->store = fd_store;
12855682Smarkm    sp->seek = fd_seek;
129233294Sstas    sp->trunc = fd_trunc;
130178825Sdfr    sp->free = fd_free;
131233294Sstas    sp->max_alloc = UINT_MAX/8;
13255682Smarkm    return sp;
13355682Smarkm}
134