17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5fc80c0dfSnordmark  * Common Development and Distribution License (the "License").
6fc80c0dfSnordmark  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
216e91bba0SGirish Moodalbail 
227c478bd9Sstevel@tonic-gate /*
239b5bf10aSMark Haywood  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
266e91bba0SGirish Moodalbail /*
276e91bba0SGirish Moodalbail  * Utility functions used by the ipmgmtd daemon.
286e91bba0SGirish Moodalbail  */
297c478bd9Sstevel@tonic-gate 
306e91bba0SGirish Moodalbail #include <stddef.h>
316e91bba0SGirish Moodalbail #include <stdlib.h>
326e91bba0SGirish Moodalbail #include <stdio.h>
336e91bba0SGirish Moodalbail #include <syslog.h>
346e91bba0SGirish Moodalbail #include <stdarg.h>
359b5bf10aSMark Haywood #include <unistd.h>
369b5bf10aSMark Haywood #include <errno.h>
376e91bba0SGirish Moodalbail #include "ipmgmt_impl.h"
387c478bd9Sstevel@tonic-gate 
399b5bf10aSMark Haywood #define	IPMGMT_BUFSIZ	1024
409b5bf10aSMark Haywood 
416e91bba0SGirish Moodalbail void
ipmgmt_log(int pri,const char * fmt,...)426e91bba0SGirish Moodalbail ipmgmt_log(int pri, const char *fmt, ...)
437c478bd9Sstevel@tonic-gate {
446e91bba0SGirish Moodalbail 	va_list alist;
457c478bd9Sstevel@tonic-gate 
466e91bba0SGirish Moodalbail 	va_start(alist, fmt);
476e91bba0SGirish Moodalbail 	vsyslog(pri, fmt, alist);
486e91bba0SGirish Moodalbail 	va_end(alist);
497c478bd9Sstevel@tonic-gate }
509b5bf10aSMark Haywood 
519b5bf10aSMark Haywood /*
529b5bf10aSMark Haywood  * Copy a source file to a new destination. The source file will be
539b5bf10aSMark Haywood  * removed if rdonly is false (i.e., used when the source file resides
549b5bf10aSMark Haywood  * on a read-only file system).
559b5bf10aSMark Haywood  *
569b5bf10aSMark Haywood  * Returns 0 on success and errno on failure.
579b5bf10aSMark Haywood  */
589b5bf10aSMark Haywood int
ipmgmt_cpfile(const char * src,const char * dst,boolean_t rdonly)599b5bf10aSMark Haywood ipmgmt_cpfile(const char *src, const char *dst, boolean_t rdonly)
609b5bf10aSMark Haywood {
619b5bf10aSMark Haywood 	struct stat statbuf;
629b5bf10aSMark Haywood 	FILE *sfp, *dfp;
639b5bf10aSMark Haywood 	char buf[IPMGMT_BUFSIZ];
649b5bf10aSMark Haywood 	int err = 0;
659b5bf10aSMark Haywood 
66*8887b57dSGirish Moodalbail 	errno = 0;
679b5bf10aSMark Haywood 	/*
689b5bf10aSMark Haywood 	 * Attempt to open the destination file first since we
699b5bf10aSMark Haywood 	 * want to optimize for the case where it is read-only
709b5bf10aSMark Haywood 	 * and will return EROFS.
719b5bf10aSMark Haywood 	 */
729b5bf10aSMark Haywood 	if ((dfp = fopen(dst, "w+")) == NULL)
739b5bf10aSMark Haywood 		return (errno);
749b5bf10aSMark Haywood 
759b5bf10aSMark Haywood 	/*
769b5bf10aSMark Haywood 	 * Require that the source file exists.
779b5bf10aSMark Haywood 	 */
789b5bf10aSMark Haywood 	if (stat(src, &statbuf) != 0) {
799b5bf10aSMark Haywood 		err = errno;
809b5bf10aSMark Haywood 		(void) fclose(dfp);
819b5bf10aSMark Haywood 		return (err);
829b5bf10aSMark Haywood 	}
839b5bf10aSMark Haywood 	if ((sfp = fopen(src, "r")) == NULL) {
849b5bf10aSMark Haywood 		err = errno;
859b5bf10aSMark Haywood 		(void) fclose(dfp);
869b5bf10aSMark Haywood 		return (err);
879b5bf10aSMark Haywood 	}
889b5bf10aSMark Haywood 
899b5bf10aSMark Haywood 	/*
909b5bf10aSMark Haywood 	 * Copy the file.
919b5bf10aSMark Haywood 	 */
92*8887b57dSGirish Moodalbail 	while (fgets(buf, sizeof (buf), sfp) != NULL && errno == 0) {
93*8887b57dSGirish Moodalbail 		(void) fputs(buf, dfp);
949b5bf10aSMark Haywood 		if (errno != 0)
959b5bf10aSMark Haywood 			break;
969b5bf10aSMark Haywood 	}
979b5bf10aSMark Haywood 	if (errno != 0)
989b5bf10aSMark Haywood 		err = errno;
99*8887b57dSGirish Moodalbail 	else if (fflush(dfp) == EOF)
100*8887b57dSGirish Moodalbail 		err = errno;
1019b5bf10aSMark Haywood 
1029b5bf10aSMark Haywood 	(void) fclose(sfp);
1039b5bf10aSMark Haywood 	(void) fclose(dfp);
1049b5bf10aSMark Haywood 
1059b5bf10aSMark Haywood 	/*
1069b5bf10aSMark Haywood 	 * If any error occurred, then remove the destination file.
1079b5bf10aSMark Haywood 	 */
1089b5bf10aSMark Haywood 	if (err != 0) {
1099b5bf10aSMark Haywood 		(void) unlink(dst);
1109b5bf10aSMark Haywood 		return (err);
1119b5bf10aSMark Haywood 	}
1129b5bf10aSMark Haywood 
1139b5bf10aSMark Haywood 	/*
1149b5bf10aSMark Haywood 	 * Make sure the file attributes are correct.
1159b5bf10aSMark Haywood 	 */
1169b5bf10aSMark Haywood 	if (chmod(dst, IPADM_FILE_MODE) != 0 ||
1179b5bf10aSMark Haywood 	    chown(dst, UID_NETADM, GID_NETADM) != 0) {
1189b5bf10aSMark Haywood 		err = errno;
1199b5bf10aSMark Haywood 		(void) unlink(dst);
1209b5bf10aSMark Haywood 		return (err);
1219b5bf10aSMark Haywood 	}
1229b5bf10aSMark Haywood 
1239b5bf10aSMark Haywood 	/*
1249b5bf10aSMark Haywood 	 * If the source file does not reside on a read-only file system
1259b5bf10aSMark Haywood 	 * then remove it.
1269b5bf10aSMark Haywood 	 */
1279b5bf10aSMark Haywood 	if (!rdonly)
1289b5bf10aSMark Haywood 		(void) unlink(src);
1299b5bf10aSMark Haywood 
1309b5bf10aSMark Haywood 	return (0);
1319b5bf10aSMark Haywood }
132