1 /* $OpenBSD: nullopen.c,v 1.4 2011/09/22 10:41:04 deraadt Exp $ */ 2 3 /* 4 * Copyright (c) 2003 Can Erkin Acar 5 * Copyright (c) 1997 Michael Shalayeff 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 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 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 */ 30 31 #include <sys/types.h> 32 #include <stdio.h> 33 #include <stdlib.h> 34 #include <errno.h> 35 #include <unistd.h> 36 #include "compress.h" 37 38 typedef struct { 39 off_t total_in; 40 off_t total_out; 41 int fd; 42 int gotmagic; 43 char mode; 44 } null_stream; 45 46 char null_magic[2]; 47 48 49 void * 50 null_open(int fd, const char *mode, char *name, int bits, 51 u_int32_t mtime, int gotmagic) 52 { 53 null_stream *s; 54 55 if (fd < 0 || !mode) 56 return NULL; 57 58 if ((mode[0] != 'r' && mode[0] != 'w') || mode[1] != '\0') { 59 errno = EINVAL; 60 return NULL; 61 } 62 63 if ((s = (null_stream *) calloc(1, sizeof(null_stream))) == NULL) 64 return NULL; 65 66 s->fd = fd; 67 s->gotmagic = gotmagic; 68 s->total_in = s->total_out = 0; 69 s->mode = mode[0]; 70 71 return s; 72 } 73 74 int 75 null_close(void *cookie, struct z_info *info, const char *name, struct stat *sb) 76 { 77 null_stream *s = (null_stream*) cookie; 78 int err = 0; 79 80 if (s == NULL) 81 return -1; 82 83 84 if (info != NULL) { 85 info->mtime = 0; 86 info->crc = (u_int32_t)-1; 87 info->hlen = 0; 88 info->total_in = (off_t) s->total_in; 89 info->total_out = (off_t) s->total_out; 90 } 91 92 setfile(name, s->fd, sb); 93 err = close(s->fd); 94 95 free(s); 96 97 return err; 98 } 99 100 int 101 null_flush(void *cookie, int flush) 102 { 103 null_stream *s = (null_stream*)cookie; 104 105 if (s == NULL || s->mode != 'w') { 106 errno = EBADF; 107 return (-1); 108 } 109 110 return 0; 111 } 112 113 int 114 null_read(void *cookie, char *buf, int len) 115 { 116 null_stream *s = (null_stream*)cookie; 117 118 if (s == NULL) { 119 errno = EBADF; 120 return (-1); 121 } 122 if (s->gotmagic) { 123 if (len < 2) { 124 errno = EBADF; 125 return (-1); 126 } 127 128 buf[0] = null_magic[0]; 129 buf[1] = null_magic[1]; 130 s->gotmagic = 0; 131 132 return (2); 133 } 134 135 return read(s->fd, buf, len); 136 } 137 138 int 139 null_write(void *cookie, const char *buf, int len) 140 { 141 null_stream *s = (null_stream*)cookie; 142 143 if (s == NULL) { 144 errno = EBADF; 145 return (-1); 146 } 147 148 return write(s->fd, buf, len); 149 } 150