1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25
26/*
27 * Utility functions used by the ipmgmtd daemon.
28 */
29
30#include <stddef.h>
31#include <stdlib.h>
32#include <stdio.h>
33#include <syslog.h>
34#include <stdarg.h>
35#include <unistd.h>
36#include <errno.h>
37#include "ipmgmt_impl.h"
38
39#define	IPMGMT_BUFSIZ	1024
40
41void
42ipmgmt_log(int pri, const char *fmt, ...)
43{
44	va_list alist;
45
46	va_start(alist, fmt);
47	vsyslog(pri, fmt, alist);
48	va_end(alist);
49}
50
51/*
52 * Copy a source file to a new destination. The source file will be
53 * removed if rdonly is false (i.e., used when the source file resides
54 * on a read-only file system).
55 *
56 * Returns 0 on success and errno on failure.
57 */
58int
59ipmgmt_cpfile(const char *src, const char *dst, boolean_t rdonly)
60{
61	struct stat statbuf;
62	FILE *sfp, *dfp;
63	char buf[IPMGMT_BUFSIZ];
64	int err = 0;
65
66	errno = 0;
67	/*
68	 * Attempt to open the destination file first since we
69	 * want to optimize for the case where it is read-only
70	 * and will return EROFS.
71	 */
72	if ((dfp = fopen(dst, "w+")) == NULL)
73		return (errno);
74
75	/*
76	 * Require that the source file exists.
77	 */
78	if (stat(src, &statbuf) != 0) {
79		err = errno;
80		(void) fclose(dfp);
81		return (err);
82	}
83	if ((sfp = fopen(src, "r")) == NULL) {
84		err = errno;
85		(void) fclose(dfp);
86		return (err);
87	}
88
89	/*
90	 * Copy the file.
91	 */
92	while (fgets(buf, sizeof (buf), sfp) != NULL && errno == 0) {
93		(void) fputs(buf, dfp);
94		if (errno != 0)
95			break;
96	}
97	if (errno != 0)
98		err = errno;
99	else if (fflush(dfp) == EOF)
100		err = errno;
101
102	(void) fclose(sfp);
103	(void) fclose(dfp);
104
105	/*
106	 * If any error occurred, then remove the destination file.
107	 */
108	if (err != 0) {
109		(void) unlink(dst);
110		return (err);
111	}
112
113	/*
114	 * Make sure the file attributes are correct.
115	 */
116	if (chmod(dst, IPADM_FILE_MODE) != 0 ||
117	    chown(dst, UID_NETADM, GID_NETADM) != 0) {
118		err = errno;
119		(void) unlink(dst);
120		return (err);
121	}
122
123	/*
124	 * If the source file does not reside on a read-only file system
125	 * then remove it.
126	 */
127	if (!rdonly)
128		(void) unlink(src);
129
130	return (0);
131}
132