1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers. 3*7c478bd9Sstevel@tonic-gate * All rights reserved. 4*7c478bd9Sstevel@tonic-gate * Copyright (c) 1990, 1993 5*7c478bd9Sstevel@tonic-gate * The Regents of the University of California. All rights reserved. 6*7c478bd9Sstevel@tonic-gate * 7*7c478bd9Sstevel@tonic-gate * This code is derived from software contributed to Berkeley by 8*7c478bd9Sstevel@tonic-gate * Chris Torek. 9*7c478bd9Sstevel@tonic-gate * 10*7c478bd9Sstevel@tonic-gate * By using this file, you agree to the terms and conditions set 11*7c478bd9Sstevel@tonic-gate * forth in the LICENSE file which can be found at the top level of 12*7c478bd9Sstevel@tonic-gate * the sendmail distribution. 13*7c478bd9Sstevel@tonic-gate */ 14*7c478bd9Sstevel@tonic-gate 15*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 16*7c478bd9Sstevel@tonic-gate 17*7c478bd9Sstevel@tonic-gate #include <sm/gen.h> 18*7c478bd9Sstevel@tonic-gate SM_RCSID("@(#)$Id: fread.c,v 1.26 2001/02/28 20:54:03 ca Exp $") 19*7c478bd9Sstevel@tonic-gate #include <string.h> 20*7c478bd9Sstevel@tonic-gate #include <errno.h> 21*7c478bd9Sstevel@tonic-gate #include <sm/io.h> 22*7c478bd9Sstevel@tonic-gate #include <sm/assert.h> 23*7c478bd9Sstevel@tonic-gate #include "local.h" 24*7c478bd9Sstevel@tonic-gate 25*7c478bd9Sstevel@tonic-gate /* 26*7c478bd9Sstevel@tonic-gate ** SM_IO_READ -- read data from the file pointer 27*7c478bd9Sstevel@tonic-gate ** 28*7c478bd9Sstevel@tonic-gate ** Parameters: 29*7c478bd9Sstevel@tonic-gate ** fp -- file pointer to read from 30*7c478bd9Sstevel@tonic-gate ** timeout -- time to complete the read 31*7c478bd9Sstevel@tonic-gate ** buf -- location to place read data 32*7c478bd9Sstevel@tonic-gate ** size -- size of each chunk of data 33*7c478bd9Sstevel@tonic-gate ** 34*7c478bd9Sstevel@tonic-gate ** Returns: 35*7c478bd9Sstevel@tonic-gate ** Failure: returns 0 (zero) _and_ sets errno 36*7c478bd9Sstevel@tonic-gate ** Success: returns the number of whole chunks read. 37*7c478bd9Sstevel@tonic-gate ** 38*7c478bd9Sstevel@tonic-gate ** A read returning 0 (zero) is only an indication of error when errno 39*7c478bd9Sstevel@tonic-gate ** has been set. 40*7c478bd9Sstevel@tonic-gate */ 41*7c478bd9Sstevel@tonic-gate 42*7c478bd9Sstevel@tonic-gate size_t 43*7c478bd9Sstevel@tonic-gate sm_io_read(fp, timeout, buf, size) 44*7c478bd9Sstevel@tonic-gate SM_FILE_T *fp; 45*7c478bd9Sstevel@tonic-gate int timeout; 46*7c478bd9Sstevel@tonic-gate void *buf; 47*7c478bd9Sstevel@tonic-gate size_t size; 48*7c478bd9Sstevel@tonic-gate { 49*7c478bd9Sstevel@tonic-gate register size_t resid = size; 50*7c478bd9Sstevel@tonic-gate register char *p; 51*7c478bd9Sstevel@tonic-gate register int r; 52*7c478bd9Sstevel@tonic-gate 53*7c478bd9Sstevel@tonic-gate SM_REQUIRE_ISA(fp, SmFileMagic); 54*7c478bd9Sstevel@tonic-gate 55*7c478bd9Sstevel@tonic-gate if (fp->f_read == NULL) 56*7c478bd9Sstevel@tonic-gate { 57*7c478bd9Sstevel@tonic-gate errno = ENODEV; 58*7c478bd9Sstevel@tonic-gate return 0; 59*7c478bd9Sstevel@tonic-gate } 60*7c478bd9Sstevel@tonic-gate 61*7c478bd9Sstevel@tonic-gate /* 62*7c478bd9Sstevel@tonic-gate ** The ANSI standard requires a return value of 0 for a count 63*7c478bd9Sstevel@tonic-gate ** or a size of 0. Peculiarily, it imposes no such requirements 64*7c478bd9Sstevel@tonic-gate ** on fwrite; it only requires read to be broken. 65*7c478bd9Sstevel@tonic-gate */ 66*7c478bd9Sstevel@tonic-gate 67*7c478bd9Sstevel@tonic-gate if (resid == 0) 68*7c478bd9Sstevel@tonic-gate return 0; 69*7c478bd9Sstevel@tonic-gate if (fp->f_r < 0) 70*7c478bd9Sstevel@tonic-gate fp->f_r = 0; 71*7c478bd9Sstevel@tonic-gate p = buf; 72*7c478bd9Sstevel@tonic-gate while ((int) resid > (r = fp->f_r)) 73*7c478bd9Sstevel@tonic-gate { 74*7c478bd9Sstevel@tonic-gate (void) memcpy((void *) p, (void *) fp->f_p, (size_t) r); 75*7c478bd9Sstevel@tonic-gate fp->f_p += r; 76*7c478bd9Sstevel@tonic-gate /* fp->f_r = 0 ... done in sm_refill */ 77*7c478bd9Sstevel@tonic-gate p += r; 78*7c478bd9Sstevel@tonic-gate resid -= r; 79*7c478bd9Sstevel@tonic-gate if ((fp->f_flags & SMNOW) != 0 && r > 0) 80*7c478bd9Sstevel@tonic-gate { 81*7c478bd9Sstevel@tonic-gate /* 82*7c478bd9Sstevel@tonic-gate ** Take whatever we have available. Spend no more time 83*7c478bd9Sstevel@tonic-gate ** trying to get all that has been requested. 84*7c478bd9Sstevel@tonic-gate ** This is needed on some file types (such as 85*7c478bd9Sstevel@tonic-gate ** SASL) that would jam when given extra, untimely 86*7c478bd9Sstevel@tonic-gate ** reads. 87*7c478bd9Sstevel@tonic-gate */ 88*7c478bd9Sstevel@tonic-gate 89*7c478bd9Sstevel@tonic-gate fp->f_r -= r; 90*7c478bd9Sstevel@tonic-gate return size - resid; 91*7c478bd9Sstevel@tonic-gate } 92*7c478bd9Sstevel@tonic-gate if (sm_refill(fp, timeout) != 0) 93*7c478bd9Sstevel@tonic-gate { 94*7c478bd9Sstevel@tonic-gate /* no more input: return partial result */ 95*7c478bd9Sstevel@tonic-gate return size - resid; 96*7c478bd9Sstevel@tonic-gate } 97*7c478bd9Sstevel@tonic-gate } 98*7c478bd9Sstevel@tonic-gate (void) memcpy((void *) p, (void *) fp->f_p, resid); 99*7c478bd9Sstevel@tonic-gate fp->f_r -= resid; 100*7c478bd9Sstevel@tonic-gate fp->f_p += resid; 101*7c478bd9Sstevel@tonic-gate return size; 102*7c478bd9Sstevel@tonic-gate } 103