aboutsummaryrefslogtreecommitdiff
path: root/src/common/utils.c
blob: 70094e8857a7a1d7b8e6e28341f9df808aa88fc2 (plain)
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/*
 * utils.c
 * Miscellaneous utils.
 *
 * Matej Pfajfar <mp292@cam.ac.uk>
 */

/*
 * Changes :
 * $Log$
 * Revision 1.2  2002/09/03 18:44:23  nickm
 * Port to MacOS X
 *
 * Revision 1.1.1.1  2002/06/26 22:45:50  arma
 * initial commit: current code
 *
 * Revision 1.6  2002/03/03 00:06:45  mp292
 * Modifications to support re-transmission.
 *
 * Revision 1.5  2002/01/29 02:22:41  mp292
 * Bugfix.
 *
 * Revision 1.4  2002/01/29 00:58:23  mp292
 * Timeout parametes to read_tout() and write_tout() are now pointers.
 *
 * Revision 1.3  2002/01/27 19:24:16  mp292
 * Added read_tout(), write_tout() which read/write from a blocking socket but
 * impose a timeout on the I/O operation.
 *
 * Revision 1.2  2002/01/26 19:30:09  mp292
 * Reviewed according to Secure-Programs-HOWTO.
 *
 * Revision 1.1  2001/12/14 09:18:00  badbytes
 * *** empty log message ***
 *
 */

#include <ctype.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>

#include "utils.h"
#include "log.h"

/* converts string to lower case */
unsigned char *stolower(unsigned char *str)
{
  int i=0;
  
  if (str) /* valid parameters */
  {
    for (i=0; str[i] != 0; i++)
      str[i] = tolower(str[i]);
  
    return str;
  }
  else return NULL;
}

/* reads data from a descriptor, just like read(), but imposes a timeout */
/* the timeout refers to the connection being idle, not to a time limit in which the data
 * should be received*/
int read_tout(int s, unsigned char *buf, size_t buflen, int flags, struct timeval *conn_tout)
{
  int retval=0;
  int received = 0;
  struct timeval tout;
  
  fd_set mask,rmask;

  FD_ZERO(&mask);
  FD_SET(s,&mask);
  
  while(1)
  {
    rmask=mask;
    tout = *conn_tout;
    retval = select(s+1,&rmask,NULL,NULL,&tout);
    if (retval == -1)
    {
      if (errno == EINTR)
	continue;
      else
	return -1;
    }
    
    if (FD_ISSET(s,&rmask))
    {
      retval = read(s,buf+received,buflen-received);
      if (retval <= 0)
	return -1;
      else
      {
	received += retval;
	if ((received < buflen) && (flags == MSG_WAITALL))
	  continue;
	else
	  return received;
      }
    }
    else
      return -1;
  }
}

/* writes data to a file descriptor, just like write(), but imposes a timeout */
/* again this refers to the connection being idle, not a time limit in which the data should
 * be sent */
int write_tout(int s, unsigned char *buf, size_t buflen, struct timeval *conn_tout)
{
  int retval = 0;
  int sent = 0;
  fd_set mask,wmask;
  struct timeval tout;
  
  FD_ZERO(&mask);
  FD_SET(s,&mask);
  
  while(1)
  {
    wmask = mask;
    tout = *conn_tout;
    retval = select(s+1,NULL,&wmask,NULL, &tout);
    if (retval == -1)
    {
      if (errno == EINTR)
	continue;
      else
	return -1;
    }
    
    if (FD_ISSET(s,&wmask))
    {
      retval = write(s,buf+sent,buflen-sent);
      if (retval < 0)
	return -1;
      else
      {
	sent += retval;
	if (sent < buflen)
	  continue;
	else
	  return sent;
      }
    }
    else
      return -1;
  }
}