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