/ lib / krb5 / store_fd.c
store_fd.c
  1  /*
  2   * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan
  3   * (Royal Institute of Technology, Stockholm, Sweden).
  4   * All rights reserved.
  5   *
  6   * Redistribution and use in source and binary forms, with or without
  7   * modification, are permitted provided that the following conditions
  8   * are met:
  9   *
 10   * 1. Redistributions of source code must retain the above copyright
 11   *    notice, this list of conditions and the following disclaimer.
 12   *
 13   * 2. Redistributions in binary form must reproduce the above copyright
 14   *    notice, this list of conditions and the following disclaimer in the
 15   *    documentation and/or other materials provided with the distribution.
 16   *
 17   * 3. Neither the name of the Institute nor the names of its contributors
 18   *    may be used to endorse or promote products derived from this software
 19   *    without specific prior written permission.
 20   *
 21   * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
 22   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 23   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 24   * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
 25   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 26   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 27   * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 28   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 29   * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 30   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 31   * SUCH DAMAGE.
 32   */
 33  
 34  #include "krb5_locl.h"
 35  #include "store-int.h"
 36  
 37  typedef struct fd_storage {
 38      int fd;
 39  } fd_storage;
 40  
 41  #define FD(S) (((fd_storage*)(S)->data)->fd)
 42  
 43  static ssize_t
 44  fd_fetch(krb5_storage * sp, void *data, size_t size)
 45  {
 46      return net_read(FD(sp), data, size);
 47  }
 48  
 49  static ssize_t
 50  fd_store(krb5_storage * sp, const void *data, size_t size)
 51  {
 52      return net_write(FD(sp), data, size);
 53  }
 54  
 55  static off_t
 56  fd_seek(krb5_storage * sp, off_t offset, int whence)
 57  {
 58      return lseek(FD(sp), offset, whence);
 59  }
 60  
 61  static int
 62  fd_trunc(krb5_storage * sp, off_t offset)
 63  {
 64      if (ftruncate(FD(sp), offset) == -1)
 65  	return errno;
 66      return 0;
 67  }
 68  
 69  static void
 70  fd_free(krb5_storage * sp)
 71  {
 72      close(FD(sp));
 73  }
 74  
 75  /**
 76   *
 77   *
 78   * @return A krb5_storage on success, or NULL on out of memory error.
 79   *
 80   * @ingroup krb5_storage
 81   *
 82   * @sa krb5_storage_emem()
 83   * @sa krb5_storage_from_mem()
 84   * @sa krb5_storage_from_readonly_mem()
 85   * @sa krb5_storage_from_data()
 86   */
 87  
 88  KRB5_LIB_FUNCTION krb5_storage * KRB5_LIB_CALL
 89  krb5_storage_from_fd(krb5_socket_t fd_in)
 90  {
 91      krb5_storage *sp;
 92      int fd;
 93  
 94  #ifdef SOCKET_IS_NOT_AN_FD
 95  #ifdef _MSC_VER
 96      if (_get_osfhandle(fd_in) != -1) {
 97  	fd = dup(fd_in);
 98      } else {
 99  	fd = _open_osfhandle(fd_in, 0);
100      }
101  #else
102  #error Dont know how to deal with fd that may or may not be a socket.
103  #endif
104  #else  /* SOCKET_IS_NOT_AN_FD */
105      fd = dup(fd_in);
106  #endif
107  
108      if (fd < 0)
109  	return NULL;
110  
111      sp = malloc(sizeof(krb5_storage));
112      if (sp == NULL) {
113  	close(fd);
114  	return NULL;
115      }
116  
117      sp->data = malloc(sizeof(fd_storage));
118      if (sp->data == NULL) {
119  	close(fd);
120  	free(sp);
121  	return NULL;
122      }
123      sp->flags = 0;
124      sp->eof_code = HEIM_ERR_EOF;
125      FD(sp) = fd;
126      sp->fetch = fd_fetch;
127      sp->store = fd_store;
128      sp->seek = fd_seek;
129      sp->trunc = fd_trunc;
130      sp->free = fd_free;
131      sp->max_alloc = UINT_MAX/8;
132      return sp;
133  }