chiark / gitweb /
socket: properly serialize/desrialize mqueue fds
[elogind.git] / src / core / hostname-setup.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2010 Lennart Poettering
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <unistd.h>
23 #include <stdio.h>
24 #include <errno.h>
25 #include <string.h>
26 #include <stdlib.h>
27
28 #include "hostname-setup.h"
29 #include "macro.h"
30 #include "util.h"
31 #include "log.h"
32
33 #if defined(TARGET_ALTLINUX) || defined(TARGET_MANDRIVA) || defined(TARGET_MAGEIA)
34 #define FILENAME "/etc/sysconfig/network"
35 #elif defined(TARGET_SUSE) || defined(TARGET_SLACKWARE)
36 #define FILENAME "/etc/HOSTNAME"
37 #elif defined(TARGET_GENTOO)
38 #define FILENAME "/etc/conf.d/hostname"
39 #endif
40
41 static int read_and_strip_hostname(const char *path, char **hn) {
42         char *s;
43         int r;
44
45         assert(path);
46         assert(hn);
47
48         r = read_one_line_file(path, &s);
49         if (r < 0)
50                 return r;
51
52         hostname_cleanup(s);
53
54         if (isempty(s)) {
55                 free(s);
56                 return -ENOENT;
57         }
58
59         *hn = s;
60
61         return 0;
62 }
63
64 static int read_distro_hostname(char **hn) {
65
66 #if defined(TARGET_GENTOO) || defined(TARGET_ALTLINUX) || defined(TARGET_MANDRIVA) || defined(TARGET_MAGEIA)
67         int r;
68         _cleanup_fclose_ FILE *f = NULL;
69
70         assert(hn);
71
72         f = fopen(FILENAME, "re");
73         if (!f)
74                 return -errno;
75
76         for (;;) {
77                 char line[LINE_MAX];
78                 char *s, *k;
79
80                 if (!fgets(line, sizeof(line), f)) {
81                         if (feof(f))
82                                 break;
83
84                         r = -errno;
85                         goto finish;
86                 }
87
88                 s = strstrip(line);
89
90                 if (!startswith_no_case(s, "HOSTNAME="))
91                         continue;
92
93                 k = strdup(s+9);
94                 if (!k) {
95                         r = -ENOMEM;
96                         goto finish;
97                 }
98
99                 hostname_cleanup(k);
100
101                 if (isempty(k)) {
102                         free(k);
103                         r = -ENOENT;
104                         goto finish;
105                 }
106
107                 *hn = k;
108                 r = 0;
109                 goto finish;
110         }
111
112         r = -ENOENT;
113
114 finish:
115         return r;
116
117 #elif defined(TARGET_SUSE) || defined(TARGET_SLACKWARE)
118         return read_and_strip_hostname(FILENAME, hn);
119 #else
120         return -ENOENT;
121 #endif
122 }
123
124 static int read_hostname(char **hn) {
125         int r;
126
127         assert(hn);
128
129         /* First, try to load the generic hostname configuration file,
130          * that we support on all distributions */
131
132         r = read_and_strip_hostname("/etc/hostname", hn);
133         if (r < 0) {
134                 if (r == -ENOENT)
135                         return read_distro_hostname(hn);
136
137                 return r;
138         }
139
140         return 0;
141 }
142
143 int hostname_setup(void) {
144         int r;
145         char *b = NULL;
146         const char *hn = NULL;
147         bool enoent = false;
148
149         r = read_hostname(&b);
150         if (r < 0) {
151                 hn = NULL;
152
153                 if (r == -ENOENT)
154                         enoent = true;
155                 else
156                         log_warning("Failed to read configured hostname: %s", strerror(-r));
157         } else
158                 hn = b;
159
160         if (isempty(hn)) {
161                 /* Don't override the hostname if it is already set
162                  * and not explicitly configured */
163                 if (hostname_is_set())
164                         goto finish;
165
166                 if (enoent)
167                         log_info("No hostname configured.");
168
169                 hn = "localhost";
170         }
171
172         if (sethostname(hn, strlen(hn)) < 0) {
173                 log_warning("Failed to set hostname to <%s>: %m", hn);
174                 r = -errno;
175         } else
176                 log_info("Set hostname to <%s>.", hn);
177
178 finish:
179         free(b);
180
181         return r;
182 }