chiark / gitweb /
nss-myhostname: move to subdirectory
[elogind.git] / src / nss-myhostname / legacy.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of nss-myhostname.
5
6   Copyright 2008-2011 Lennart Poettering
7   Copyright 2011 Robert millan
8
9   nss-myhostname is free software; you can redistribute it and/or
10   modify it under the terms of the GNU Lesser General Public License
11   as published by the Free Software Foundation; either version 2.1 of
12   the License, or (at your option) any later version.
13
14   nss-myhostname is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17   Lesser General Public License for more details.
18
19   You should have received a copy of the GNU Lesser General Public
20   License along with nss-myhostname; If not, see
21   <http://www.gnu.org/licenses/>.
22 ***/
23
24 #include <sys/types.h>
25 #include <errno.h>
26 #include <ifaddrs.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <netinet/in.h>
30
31 #include "ifconf.h"
32
33 int ifconf_acquire_addresses(struct address **_list, unsigned *_n_list) {
34         struct address *list = NULL;
35         unsigned n_list = 0;
36         struct ifaddrs *ifa = NULL;
37         int r = 1;
38         struct ifaddrs *i;
39         int ifindex = 0;
40
41         if (getifaddrs(&ifa) == -1) {
42                 r = -errno;
43                 goto finish;
44         }
45
46         for (i = ifa; i != NULL; i = i->ifa_next) {
47                 int af;
48                 const void *cp;
49                 struct sockaddr_in6 *in6 = (struct sockaddr_in6 *) i->ifa_addr;
50                 struct sockaddr_in *in = (struct sockaddr_in *) i->ifa_addr;
51
52                 if (! i->ifa_addr)
53                         continue;
54
55                 af = i->ifa_addr->sa_family;
56
57                 if (af != AF_INET && af != AF_INET6)
58                         continue;
59
60                 list = realloc(list, (n_list+1) * sizeof(struct address));
61                 if (!list) {
62                         r = -ENOMEM;
63                         goto finish;
64                 }
65
66                 if (af == AF_INET6)
67                         cp = &in6->sin6_addr;
68                 else
69                         cp = &in->sin_addr;
70
71                 list[n_list].family = af;
72                 list[n_list].scope = 0;
73                 memcpy(list[n_list].address, cp, PROTO_ADDRESS_SIZE(af));
74                 list[n_list].ifindex = ifindex++;
75                 n_list++;
76         }
77
78 finish:
79         if (ifa)
80                 freeifaddrs(ifa);
81
82         if (r < 0)
83                 free(list);
84         else {
85                 qsort(list, n_list, sizeof(struct address), address_compare);
86
87                 *_list = list;
88                 *_n_list = n_list;
89         }
90
91         return r;
92 }