server.c revision 28679
1#include <sys/types.h>
2#include <sys/stat.h>
3#include <sys/socket.h>
4#include <netinet/in.h>
5#include <sys/un.h>
6#include <arpa/inet.h>
7#include <netinet/in_systm.h>
8#include <netinet/ip.h>
9#include <string.h>
10#include <stdio.h>
11#include <errno.h>
12#include <unistd.h>
13#include "mbuf.h"
14#include "log.h"
15#include "loadalias.h"
16#include "vars.h"
17#include "server.h"
18
19int server = UNKNOWN_SERVER;
20static struct sockaddr_un ifsun;
21static char *rm;
22
23int
24ServerLocalOpen(const char *name, mode_t mask)
25{
26  int s;
27
28  ifsun.sun_len = strlen(name);
29  if (ifsun.sun_len > sizeof ifsun.sun_path - 1) {
30    LogPrintf(LogERROR, "Local: %s: Path too long\n", name);
31    return 1;
32  }
33  ifsun.sun_family = AF_LOCAL;
34  strcpy(ifsun.sun_path, name);
35
36  s = socket(PF_LOCAL, SOCK_STREAM, 0);
37  if (s < 0) {
38    LogPrintf(LogERROR, "Local: socket: %s\n", strerror(errno));
39    return 2;
40  }
41  setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &s, sizeof s);
42  mask = umask(mask);
43  if (bind(s, (struct sockaddr *) & ifsun, sizeof(ifsun)) < 0) {
44    umask(mask);
45    LogPrintf(LogERROR, "Local: bind: %s\n", strerror(errno));
46    if (errno == EADDRINUSE && VarTerm)
47      fprintf(VarTerm, "Wait for a while, then try again.\n");
48    close(s);
49    unlink(name);
50    return 3;
51  }
52  umask(mask);
53  if (listen(s, 5) != 0) {
54    LogPrintf(LogERROR, "Local: Unable to listen to socket - OS overload?\n");
55    close(s);
56    unlink(name);
57    return 4;
58  }
59  ServerClose();
60  server = s;
61  rm = ifsun.sun_path;
62  LogPrintf(LogPHASE, "Listening at local socket %s.\n", name);
63  return 0;
64}
65
66int
67ServerTcpOpen(int port)
68{
69  struct sockaddr_in ifsin;
70  int s;
71
72  s = socket(PF_INET, SOCK_STREAM, 0);
73  if (s < 0) {
74    LogPrintf(LogERROR, "Tcp: socket: %s\n", strerror(errno));
75    return 5;
76  }
77  ifsin.sin_family = AF_INET;
78  ifsin.sin_addr.s_addr = INADDR_ANY;
79  ifsin.sin_port = htons(port);
80  setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &s, sizeof s);
81  if (bind(s, (struct sockaddr *) & ifsin, sizeof(ifsin)) < 0) {
82    LogPrintf(LogERROR, "Tcp: bind: %s\n", strerror(errno));
83    if (errno == EADDRINUSE && VarTerm)
84      fprintf(VarTerm, "Wait for a while, then try again.\n");
85    close(s);
86    return 6;
87  }
88  if (listen(s, 5) != 0) {
89    LogPrintf(LogERROR, "Tcp: Unable to listen to socket - OS overload?\n");
90    close(s);
91    return 7;
92  }
93  ServerClose();
94  server = s;
95  LogPrintf(LogPHASE, "Listening at port %d.\n", port);
96  return 0;
97}
98
99void
100ServerClose()
101{
102  if (server >= 0) {
103    close(server);
104    if (rm) {
105      unlink(rm);
106      rm = 0;
107    }
108  }
109  server = -1;
110}
111
112int
113ServerType()
114{
115  if (server == UNKNOWN_SERVER)
116    return UNKNOWN_SERVER;
117  else if (server == NO_SERVER)
118    return NO_SERVER;
119  else if (rm)
120    return LOCAL_SERVER;
121  else
122    return INET_SERVER;
123}
124