source: trunk/third/sendmail/libsm/fget.c @ 19204

Revision 19204, 2.4 KB checked in by zacheiss, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r19203, which included commits to RCS files with non-trunk default branches.
Line 
1/*
2 * Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers.
3 *      All rights reserved.
4 * Copyright (c) 1990, 1993
5 *      The Regents of the University of California.  All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Chris Torek.
9 *
10 * By using this file, you agree to the terms and conditions set
11 * forth in the LICENSE file which can be found at the top level of
12 * the sendmail distribution.
13 */
14
15#include <sm/gen.h>
16SM_RCSID("@(#)$Id: fget.c,v 1.1.1.1 2003-04-08 15:06:04 zacheiss Exp $")
17#include <stdlib.h>
18#include <string.h>
19#include <sm/io.h>
20#include <sm/assert.h>
21#include "local.h"
22
23/*
24**  SM_IO_FGETS -- get a string from a file
25**
26**  Read at most n-1 characters from the given file.
27**  Stop when a newline has been read, or the count ('n') runs out.
28**
29**      Parameters:
30**              fp -- the file to read from
31**              timeout -- time to complete reading the string in milliseconds
32**              buf -- buffer to place read string in
33**              n -- size of 'buf'
34**
35**      Returns:
36**              success: returns value of 'buf'
37**              failure: NULL (no characters were read)
38**              timeout: NULL and errno set to EAGAIN
39**
40**      Side Effects:
41**              may move the file pointer
42*/
43
44char *
45sm_io_fgets(fp, timeout, buf, n)
46        register SM_FILE_T *fp;
47        int timeout;
48        char *buf;
49        register int n;
50{
51        register int len;
52        register char *s;
53        register unsigned char *p, *t;
54
55        SM_REQUIRE_ISA(fp, SmFileMagic);
56        if (n <= 0)             /* sanity check */
57                return NULL;
58
59        s = buf;
60        n--;                    /* leave space for NUL */
61        while (n > 0)
62        {
63                /* If the buffer is empty, refill it. */
64                if ((len = fp->f_r) <= 0)
65                {
66
67                        /*
68                        **  Timeout is only passed if we can't get the data
69                        **  from the buffer (which is counted as immediately).
70                        */
71
72                        if (sm_refill(fp, timeout) != 0)
73                        {
74                                /* EOF/error: stop with partial or no line */
75                                if (s == buf)
76                                        return NULL;
77                                break;
78                        }
79                        len = fp->f_r;
80                }
81                p = fp->f_p;
82
83                /*
84                **  Scan through at most n bytes of the current buffer,
85                **  looking for '\n'.  If found, copy up to and including
86                **  newline, and stop.  Otherwise, copy entire chunk
87                **  and loop.
88                */
89
90                if (len > n)
91                        len = n;
92                t = (unsigned char *) memchr((void *) p, '\n', len);
93                if (t != NULL)
94                {
95                        len = ++t - p;
96                        fp->f_r -= len;
97                        fp->f_p = t;
98                        (void) memcpy((void *) s, (void *) p, len);
99                        s[len] = 0;
100                        return buf;
101                }
102                fp->f_r -= len;
103                fp->f_p += len;
104                (void) memcpy((void *) s, (void *) p, len);
105                s += len;
106                n -= len;
107        }
108        *s = 0;
109        return buf;
110}
Note: See TracBrowser for help on using the repository browser.