summaryrefslogtreecommitdiffstats
path: root/socket.c
blob: 63a4f46110215e840113a5a84d2b827b50abb670 (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
/*
 * Copyright (C) 1998 Michael R. Elkins <me@cs.hmc.edu>
 * 
 *     This program is free software; you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation; either version 2 of the License, or
 *     (at your option) any later version.
 * 
 *     This program is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU General Public License for more details.
 * 
 *     You should have received a copy of the GNU General Public License
 *     along with this program; if not, write to the Free Software
 *     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */ 

#include "mutt.h"
#include "globals.h"
#include "mutt_socket.h"

#include <unistd.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>

/* support for multiple socket connections */

static CONNECTION *Connections = NULL;
static int NumConnections = 0;

/* simple read buffering to speed things up. */
int mutt_socket_readchar (CONNECTION *conn, char *c)
{
  if (conn->bufpos >= conn->available)
  {
    conn->available = read (conn->fd, conn->inbuf, LONG_STRING);
    dprint (1, (debugfile, "mutt_socket_readchar(): buffered %d chars\n", conn->available));
    conn->bufpos = 0;
    if (conn->available <= 0)
      return conn->available; /* returns 0 for EOF or -1 for other error */
  }
  *c = conn->inbuf[conn->bufpos];
  conn->bufpos++;
  return 1;
}

int mutt_socket_read_line (char *buf, size_t buflen, CONNECTION *conn)
{
  char ch;
  int i;

  for (i = 0; i < buflen; i++)
  {
    if (mutt_socket_readchar (conn, &ch) != 1)
      return (-1);
    if (ch == '\n')
      break;
    buf[i] = ch;
  }
  buf[i-1] = 0;
  return (i + 1);
}

int mutt_socket_read_line_d (char *buf, size_t buflen, CONNECTION *conn)
{
  int r = mutt_socket_read_line (buf, buflen, conn);
  dprint (1,(debugfile,"mutt_socket_read_line_d():%s\n", buf));
  return r;
}

int mutt_socket_write (CONNECTION *conn, const char *buf)
{
  dprint (1,(debugfile,"mutt_socket_write():%s", buf));
  return (write (conn->fd, buf, strlen (buf)));
}

CONNECTION *mutt_socket_select_connection (char *host, int port, int flags)
{
  int x;

  if (flags != M_NEW_SOCKET)
  {
    for (x = 0; x < NumConnections; x++)
    {
      if (!strcmp (host, Connections[x].server) && 
	  (port == Connections[x].port))
	return &Connections[x];
    }
  }
  if (NumConnections == 0)
  {
    NumConnections = 1;
    Connections = (CONNECTION *) safe_malloc (sizeof (CONNECTION));
  }
  else
  {
    NumConnections++;
    safe_realloc ((void *)&Connections, sizeof (CONNECTION) * NumConnections);
  }
  Connections[NumConnections - 1].bufpos = 0;
  Connections[NumConnections - 1].available = 0;
  Connections[NumConnections - 1].uses = 0;
  Connections[NumConnections - 1].server = safe_strdup (host);
  Connections[NumConnections - 1].port = port;

  return &Connections[NumConnections - 1];
}