summaryrefslogtreecommitdiff
path: root/usr/src/cmd/cmd-inet/lib/ipmgmtd/ipmgmt_util.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd/cmd-inet/lib/ipmgmtd/ipmgmt_util.c')
-rw-r--r--usr/src/cmd/cmd-inet/lib/ipmgmtd/ipmgmt_util.c88
1 files changed, 86 insertions, 2 deletions
diff --git a/usr/src/cmd/cmd-inet/lib/ipmgmtd/ipmgmt_util.c b/usr/src/cmd/cmd-inet/lib/ipmgmtd/ipmgmt_util.c
index 8ef9a09e3d..704dab2d36 100644
--- a/usr/src/cmd/cmd-inet/lib/ipmgmtd/ipmgmt_util.c
+++ b/usr/src/cmd/cmd-inet/lib/ipmgmtd/ipmgmt_util.c
@@ -20,8 +20,7 @@
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
@@ -33,8 +32,12 @@
#include <stdio.h>
#include <syslog.h>
#include <stdarg.h>
+#include <unistd.h>
+#include <errno.h>
#include "ipmgmt_impl.h"
+#define IPMGMT_BUFSIZ 1024
+
void
ipmgmt_log(int pri, const char *fmt, ...)
{
@@ -44,3 +47,84 @@ ipmgmt_log(int pri, const char *fmt, ...)
vsyslog(pri, fmt, alist);
va_end(alist);
}
+
+/*
+ * Copy a source file to a new destination. The source file will be
+ * removed if rdonly is false (i.e., used when the source file resides
+ * on a read-only file system).
+ *
+ * Returns 0 on success and errno on failure.
+ */
+int
+ipmgmt_cpfile(const char *src, const char *dst, boolean_t rdonly)
+{
+ struct stat statbuf;
+ FILE *sfp, *dfp;
+ char buf[IPMGMT_BUFSIZ];
+ size_t bytes;
+ int err = 0;
+
+ /*
+ * Attempt to open the destination file first since we
+ * want to optimize for the case where it is read-only
+ * and will return EROFS.
+ */
+ if ((dfp = fopen(dst, "w+")) == NULL)
+ return (errno);
+
+ /*
+ * Require that the source file exists.
+ */
+ if (stat(src, &statbuf) != 0) {
+ err = errno;
+ (void) fclose(dfp);
+ return (err);
+ }
+ if ((sfp = fopen(src, "r")) == NULL) {
+ err = errno;
+ (void) fclose(dfp);
+ return (err);
+ }
+
+ /*
+ * Copy the file.
+ */
+ while (((bytes = fread(buf, 1, sizeof (buf), sfp)) != 0) &&
+ (errno == 0)) {
+ (void) fwrite(buf, bytes, 1, dfp);
+ if (errno != 0)
+ break;
+ }
+ if (errno != 0)
+ err = errno;
+
+ (void) fclose(sfp);
+ (void) fclose(dfp);
+
+ /*
+ * If any error occurred, then remove the destination file.
+ */
+ if (err != 0) {
+ (void) unlink(dst);
+ return (err);
+ }
+
+ /*
+ * Make sure the file attributes are correct.
+ */
+ if (chmod(dst, IPADM_FILE_MODE) != 0 ||
+ chown(dst, UID_NETADM, GID_NETADM) != 0) {
+ err = errno;
+ (void) unlink(dst);
+ return (err);
+ }
+
+ /*
+ * If the source file does not reside on a read-only file system
+ * then remove it.
+ */
+ if (!rdonly)
+ (void) unlink(src);
+
+ return (0);
+}