pidentd  3.0.19
About: implementation of the RFC1413 identification server (more or less complete rewrite compared to version 2)
  Fossies Dox: pidentd-3.0.19.tar.gz  ("inofficial" and yet experimental doxygen-generated source code documentation)  

server.c
Go to the documentation of this file.
1 /*
2 ** server.c - IDENT TCP/IP socket server code
3 **
4 ** Copyright (c) 1997 Peter Eriksson <pen@lysator.liu.se>
5 **
6 ** This program is free software; you can redistribute it and/or
7 ** modify it as you wish - as long as you don't claim that you wrote
8 ** it.
9 **
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 */
14 
15 #include "config.h"
16 
17 #include <syslog.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <sys/time.h>
21 #include <sys/resource.h>
22 #include <errno.h>
23 
24 #include "pidentd.h"
25 
26 
27 
28 int listen_sock = -1;
30 int listen_addr = INADDR_ANY;
31 int listen_backlog = 256;
32 
33 
34 static int
36 {
37 #ifndef RLIMIT_NOFILE
38  return 64;
39 #else
40  struct rlimit rlb;
41 
42  if (getrlimit(RLIMIT_NOFILE, &rlb) < 0)
43  {
44  syslog(LOG_ERR, "getrlimit() failed: %m");
45  return -1;
46  }
47 
48  rlb.rlim_cur = rlb.rlim_max;
49 
50  if (setrlimit(RLIMIT_NOFILE, &rlb) < 0)
51  {
52  syslog(LOG_ERR, "getrlimit() failed: %m");
53  return -1;
54  }
55 
56  return rlb.rlim_cur;
57 #endif
58 }
59 
60 
61 int
63 {
64  static int one = 1;
65  int nofile;
66  struct sockaddr_in sin;
67 
68 
69  /*
70  ** Increase the number of available file descriptors
71  ** to the maximum possible.
72  */
73  nofile = unlimit_nofile();
74  if (nofile < 0)
75  return -1;
76 
77 
78  if (listen_sock < 0)
79  {
80  listen_sock = socket(AF_INET, SOCK_STREAM, 0);
81  if (listen_sock < 0)
82  {
83  syslog(LOG_ERR, "socket(AF_INET, SOCK_STREAM) failed: %m");
84  return -1;
85  }
86 
87  (void) setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR,
88  (void *) &one, sizeof(one));
89 
90  memset(&sin, 0, sizeof(sin));
91  sin.sin_family = AF_INET;
92  sin.sin_addr.s_addr = htonl(listen_addr);
93  sin.sin_port = htons(listen_port);
94 
95  if (bind(listen_sock, (struct sockaddr *) &sin, sizeof(sin)) < 0)
96  {
97  syslog(LOG_ERR, "bind(port=%d) failed: %m",
98  listen_port);
99  return -1;
100  }
101  }
102 
103  /* We do this outside of the 'if' statement to support
104  some broken 'inetd' daemons... */
105  if (listen(listen_sock, listen_backlog) < 0)
106  {
107  syslog(LOG_ERR, "listen(backlog=%d) failed: %m", listen_backlog);
108  return -1;
109  }
110 
111  return 0;
112 }
113 
114 
115 int
117 {
118  int fd;
119 
120  while (1)
121  {
122  fd = s_accept(listen_sock, NULL, NULL);
123  if (fd < 0)
124  {
125  syslog(LOG_ERR, "accept() failed: %m");
126 
127  switch (errno)
128  {
129  case EBADF:
130  case EMFILE:
131  case ENODEV:
132  case ENOMEM:
133  case ENOTSOCK:
134  case EOPNOTSUPP:
135  case EWOULDBLOCK:
136  return -1;
137  }
138  }
139 
140  request_run(fd, 0);
141  }
142 }
IPPORT_IDENT
#define IPPORT_IDENT
Definition: system.h:28
unlimit_nofile
static int unlimit_nofile(void)
Definition: server.c:35
pidentd.h
request_run
int request_run(int fd, int nofork)
Definition: request.c:261
server_run
int server_run(void)
Definition: server.c:116
listen_addr
int listen_addr
Definition: server.c:30
listen_sock
int listen_sock
Definition: server.c:28
listen_backlog
int listen_backlog
Definition: server.c:31
server_init
int server_init(void)
Definition: server.c:62
s_accept
int s_accept(int fd, struct sockaddr *sin, socklen_t *len)
Definition: safeio.c:184
listen_port
int listen_port
Definition: server.c:29
errno
#define errno
Definition: hp_pthread.h:23