File: Sgets.c

package info (click to toggle)
dmucs 0.6.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 3,240 kB
  • sloc: ansic: 5,053; sh: 3,557; cpp: 2,397; makefile: 64; perl: 26
file content (132 lines) | stat: -rw-r--r-- 3,982 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/* Sgets.c
 * Syntax :  Sgets(buf,maxbuf,skt)
 * Returns: buf if it worked, a NULL pointer otherwise
 *
 * buf[maxbuf]
 * Authors:      Charles E. Campbell, Jr.
 *               Terry McRoberts
 * Copyright:    Copyright (C) 1999-2005 Charles E. Campbell, Jr. {{{1
 *               Permission is hereby granted to use and distribute this code,
 *               with or without modifications, provided that this copyright
 *               notice is copied with it. Like anything else that's free,
 *               Sgets.c is provided *as is* and comes with no warranty
 *               of any kind, either expressed or implied. By using this
 *               software, you agree that in no event will the copyright
 *               holder be liable for any damages resulting from the use
 *               of this software.
 * Date:         Aug 22, 2005
 */
#include <stdio.h>
#include "sockets.h"

/* ---------------------------------------------------------------------------
 * Local Definitions:
 */

/* ---------------------------------------------------------------------------
 * Function Declarations:
 */

/* ---------------------------------------------------------------------------
 * Source Code:
 */

/* Sgets:
 * Gets a null-byte terminated string from the specified Socket.
 * Note that the maxbuf *must be* >= 2 (one byte needed for the
 * null byte termination, and one byte for a minimal amount of data).
 * This function blocks and will fill the buffer "buf" with up
 * to maxbuf characters.  The output from this function will
 * be null byte terminated when successful, even on a full buffer condition.
 *
 * Returns: buf     : on success
 *          null ptr: on failure
 */
#ifdef __PROTOTYPE__
char *Sgets(
	    char   *buf,	/* holds null-byte terminated string from Socket */
	    int     maxbuf,	/* maximum size of string allowed in buf */
	    Socket *skt)	/* Socket from which data is to be read	*/
#else
char *Sgets(buf, maxbuf, skt)
    char   *buf;
    int     maxbuf;
    Socket *skt;
#endif
{
    int   buflen;
    int   mesglen;
    char *b  = NULL;
#ifndef SSLNOPEEK
    char *nb = NULL;
#endif


    /* error or whatever, until the buffer actually gets something its empty */
    buf[0] = '\0';

    /* sanity check */
    if (!skt) {
	return (char *) NULL;
    }

#ifdef SSLNOPEEK	/* stupid, so it receives one byte at a time */
    for (b = buf, buflen = maxbuf-1; buflen; --buflen, ++b) {
	if (recv(skt->skt, b, (unsigned) 1, 0) <= 0) {
	    return (char *) NULL;
	}
	if (*b == '\0') break;
    }

#else

    /* receive bytes until a nullbyte is received */
    buflen = maxbuf - 2;	/* leave space for trailing null byte		*/
    buf[buflen + 1] = '\0';	/* so strchr will find a null byte somewhere	*/
    for (b = buf, mesglen = 0; buflen > 0; b += mesglen, buflen -= mesglen) {

	/* block until something shows up on the Socket */
	if (!Swait(skt)) {    /* null == error - should be at least 1 null byte */
	    return (char *) NULL;
	}

	/* peek at contents of socket queue */
	mesglen = recv(skt->skt, b, buflen, MSG_PEEK);

	if (mesglen <= 0) {		/* socket error - bad receive */
	    return (char *) NULL;
	}
	else if (mesglen > 0) { 	/* check if null byte received yet */
	    nb = strchr(b, '\0');	/* find null byte in buffer */

	    if (nb < b + mesglen) {	/* null byte inside peeked-at message	*/
		mesglen = nb - b + 1;	/* read up to and including null byte	*/
		if (Sreadbytes(skt, b, mesglen) <= 0) {
		    return buf;
		}
		break;
	    }
	    else if (mesglen >= buflen) { 	/* whoops - full buffer	*/
		if (Sreadbytes(skt, b, buflen) <= 0) {
		    return buf;
		}
		b[buflen] = '\0';		/* end-of-buffer termination */
		break;
	    }
	    else {
		if (Sreadbytes(skt, b, mesglen) <= 0) {	/* partial read	*/
		    return buf;
		}
	    }
	}
    }

#endif	/* #ifdef SSLNOPEEK ... #else ... #endif */

    /* return message */
    return buf;
}

/* ---------------------------------------------------------------------
 * vim: ts=4
 */