GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/amd/amd/amd.c Lines: 0 66 0.0 %
Date: 2016-12-06 Branches: 0 39 0.0 %

Line Branch Exec Source
1
/*
2
 * Copyright (c) 1989 Jan-Simon Pendry
3
 * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
4
 * Copyright (c) 1989, 1993
5
 *	The Regents of the University of California.  All rights reserved.
6
 *
7
 * This code is derived from software contributed to Berkeley by
8
 * Jan-Simon Pendry at Imperial College, London.
9
 *
10
 * Redistribution and use in source and binary forms, with or without
11
 * modification, are permitted provided that the following conditions
12
 * are met:
13
 * 1. Redistributions of source code must retain the above copyright
14
 *    notice, this list of conditions and the following disclaimer.
15
 * 2. Redistributions in binary form must reproduce the above copyright
16
 *    notice, this list of conditions and the following disclaimer in the
17
 *    documentation and/or other materials provided with the distribution.
18
 * 3. Neither the name of the University nor the names of its contributors
19
 *    may be used to endorse or promote products derived from this software
20
 *    without specific prior written permission.
21
 *
22
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32
 * SUCH DAMAGE.
33
 *
34
 *	from: @(#)amd.c	8.1 (Berkeley) 6/6/93
35
 *	$Id: amd.c,v 1.22 2015/09/11 19:03:30 millert Exp $
36
 */
37
38
/*
39
 * Automounter
40
 */
41
42
#include "am.h"
43
#include <signal.h>
44
#include <sys/ioctl.h>
45
#include <sys/stat.h>
46
#include <fcntl.h>
47
#include <unistd.h>
48
#include <setjmp.h>
49
#include <endian.h>
50
51
#include <rpc/rpc.h>
52
#include <rpcsvc/ypclnt.h>
53
#include <rpcsvc/yp_prot.h>
54
55
#if BYTE_ORDER == LITTLE_ENDIAN
56
#define ARCH_ENDIAN "little"
57
#elif BYTE_ORDER == BIG_ENDIAN
58
#define ARCH_ENDIAN "big"
59
#else
60
#error "unknown endian"
61
#endif
62
63
char pid_fsname[16 + MAXHOSTNAMELEN];	/* "kiska.southseas.nz:(pid%d)" */
64
#ifdef HAS_HOST
65
#ifdef HOST_EXEC
66
char *host_helper;
67
#endif /* HOST_EXEC */
68
#endif /* HAS_HOST */
69
char *auto_dir = "/tmp_mnt";
70
char *hostdomain = "unknown.domain";
71
char hostname[MAXHOSTNAMELEN] = "localhost"; /* Hostname */
72
char hostd[2*MAXHOSTNAMELEN];		/* Host+domain */
73
char *op_sys = "bsd44";			/* Name of current op_sys */
74
char *arch = ARCH_REP;			/* Name of current architecture */
75
char *endian = ARCH_ENDIAN;		/* Big or Little endian */
76
char *wire;
77
int foreground = 1;			/* This is the top-level server */
78
pid_t mypid;				/* Current process id */
79
volatile sig_atomic_t immediate_abort;	/* Should close-down unmounts be retried */
80
struct in_addr myipaddr;		/* (An) IP address of this host */
81
serv_state amd_state;
82
struct amd_stats amd_stats;		/* Server statistics */
83
time_t do_mapc_reload = 0;		/* mapc_reload() call required? */
84
jmp_buf select_intr;
85
int select_intr_valid;
86
int orig_umask;
87
88
/*
89
 * Signal handler:
90
 * SIGINT - tells amd to do a full shutdown, including unmounting all filesystem.
91
 * SIGTERM - tells amd to shutdown now.  Just unmounts the automount nodes.
92
 */
93
static void
94
sigterm(int sig)
95
{
96
97
	switch (sig) {
98
	case SIGINT:
99
		immediate_abort = 15;
100
		break;
101
102
	case SIGTERM:
103
		immediate_abort = -1;
104
		/* fall through... */
105
106
	default:
107
		plog(XLOG_WARNING, "WARNING: automounter going down on signal %d", sig);
108
		break;
109
	}
110
	if (select_intr_valid)
111
		longjmp(select_intr, sig);
112
}
113
114
/*
115
 * Hook for cache reload.
116
 * When a SIGHUP arrives it schedules a call to mapc_reload
117
 */
118
static void
119
sighup(int sig)
120
{
121
122
#ifdef DEBUG
123
	if (sig != SIGHUP)
124
		dlog("spurious call to sighup");
125
#endif /* DEBUG */
126
	/*
127
	 * Force a reload by zero'ing the timer
128
	 */
129
	if (amd_state == Run)
130
		do_mapc_reload = 0;
131
}
132
133
static void
134
parent_exit(int sig)
135
{
136
	_exit(0);
137
}
138
139
static pid_t
140
daemon_mode(void)
141
{
142
	pid_t bgpid;
143
144
	signal(SIGQUIT, parent_exit);
145
	bgpid = background();
146
147
	if (bgpid != 0) {
148
		if (print_pid) {
149
			printf("%ld\n", (long)bgpid);
150
			fflush(stdout);
151
		}
152
		/*
153
		 * Now wait for the automount points to
154
		 * complete.
155
		 */
156
		for (;;)
157
			pause();
158
	}
159
160
	signal(SIGQUIT, SIG_DFL);
161
162
	/*
163
	 * Pretend we are in the foreground again
164
	 */
165
	foreground = 1;
166
167
#ifdef TIOCNOTTY
168
	{
169
		int t = open("/dev/tty", O_RDWR);
170
		if (t < 0) {
171
			if (errno != ENXIO)	/* not an error if already no controlling tty */
172
				plog(XLOG_WARNING, "Could not open controlling tty: %m");
173
		} else {
174
			if (ioctl(t, TIOCNOTTY, 0) < 0 && errno != ENOTTY)
175
				plog(XLOG_WARNING, "Could not disassociate tty (TIOCNOTTY): %m");
176
			(void) close(t);
177
		}
178
	}
179
#else
180
	(void) setpgrp();
181
#endif /* TIOCNOTTY */
182
183
	return getppid();
184
}
185
186
int
187
main(int argc, char *argv[])
188
{
189
	char *domdot;
190
	pid_t ppid = 0;
191
	int error;
192
193
	/*
194
	 * Make sure some built-in assumptions are true before we start
195
	 */
196
	assert(sizeof(nfscookie) >= sizeof (unsigned int));
197
	assert(sizeof(int) >= 4);
198
199
	/*
200
	 * Set processing status.
201
	 */
202
	amd_state = Start;
203
204
	/*
205
	 * Initialise process id.  This is kept
206
	 * cached since it is used for generating
207
	 * and using file handles.
208
	 */
209
	mypid = getpid();
210
211
	/*
212
	 * Get local machine name
213
	 */
214
	if (gethostname(hostname, sizeof(hostname)) < 0) {
215
		plog(XLOG_FATAL, "gethostname: %m");
216
		going_down(1);
217
	}
218
	/*
219
	 * Check it makes sense
220
	 */
221
	if (!*hostname) {
222
		plog(XLOG_FATAL, "host name is not set");
223
		going_down(1);
224
	}
225
	/*
226
	 * Partially initialise hostd[].  This
227
	 * is completed in get_args().
228
	 */
229
	if ((domdot = strchr(hostname, '.'))) {
230
		/*
231
		 * Hostname already contains domainname.
232
		 * Split out hostname and domainname
233
		 * components
234
		 */
235
		*domdot++ = '\0';
236
		hostdomain = domdot;
237
	}
238
	strlcpy(hostd, hostname, sizeof hostd);
239
240
	/*
241
	 * Trap interrupts for shutdowns.
242
	 */
243
	(void) signal(SIGINT, sigterm);
244
245
	/*
246
	 * Hangups tell us to reload the cache
247
	 */
248
	(void) signal(SIGHUP, sighup);
249
250
	/*
251
	 * Trap Terminate so that we can shutdown gracefully (some chance)
252
	 */
253
	(void) signal(SIGTERM, sigterm);
254
	/*
255
	 * Trap Death-of-a-child.  These allow us to
256
	 * pick up the exit status of backgrounded mounts.
257
	 * See "sched.c".
258
	 */
259
	(void) signal(SIGCHLD, sigchld);
260
261
	/*
262
	 * Fix-up any umask problems.  Most systems default
263
	 * to 002 which is not too convenient for our purposes
264
	 */
265
	orig_umask = umask(0);
266
267
	/*
268
	 * Figure out primary network name
269
	 */
270
	wire = getwire();
271
272
	/*
273
	 * Determine command-line arguments
274
	 */
275
	get_args(argc, argv);
276
277
	if (mkdir(auto_dir, 0755) == -1) {
278
		if (errno != EEXIST)
279
			plog(XLOG_FATAL, "mkdir(autodir = %s: %m", auto_dir);
280
	}
281
282
	/*
283
	 * Get our own IP address so that we
284
	 * can mount the automounter.
285
	 */
286
	{ struct sockaddr_in sin;
287
	  get_myaddress(&sin);
288
	  myipaddr.s_addr = sin.sin_addr.s_addr;
289
	}
290
291
	/*
292
	 * Now check we are root.
293
	 */
294
	if (geteuid() != 0) {
295
		plog(XLOG_FATAL, "Must be root to mount filesystems (euid = %u)", geteuid());
296
		going_down(1);
297
	}
298
299
	/*
300
	 * If the domain was specified then bind it here
301
	 * to circumvent any default bindings that may
302
	 * be done in the C library.
303
	 */
304
	if (domain && yp_bind(domain)) {
305
		plog(XLOG_FATAL, "Can't bind to domain \"%s\"", domain);
306
		going_down(1);
307
	}
308
309
#ifdef DEBUG
310
	Debug(D_DAEMON)
311
#endif /* DEBUG */
312
	ppid = daemon_mode();
313
314
	snprintf(pid_fsname, sizeof(pid_fsname), "%s:(pid%ld)", hostname, (long)mypid);
315
316
	do_mapc_reload = clocktime() + ONE_HOUR;
317
318
	/*
319
	 * Register automounter with system
320
	 */
321
	error = mount_automounter(ppid);
322
	if (error && ppid)
323
		kill(ppid, SIGALRM);
324
	going_down(error);
325
326
	abort();
327
}