components/visual-panels/time/src/cmd/rad/mod/time/mod_time.c
branchs11-update
changeset 3038 1a97ff5e830d
parent 3037 ef46824e0e76
child 3039 bf667aad6d27
--- a/components/visual-panels/time/src/cmd/rad/mod/time/mod_time.c	Tue Apr 01 11:11:03 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,542 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
- */
-
-#include <sys/types.h>
-#include <sys/processor.h>
-#include <sys/stat.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <time.h>
-#include <errno.h>
-#include <limits.h>
-#include <libscf.h>
-
-#include <rad/adr.h>
-#include <rad/rad_modapi.h>
-
-#include "smfutil.h"
-#include "api_time.h"
-
-#define	NTP_CONF	"/etc/inet/ntp.conf"
-#define	NTP_CONF_BAK	"/etc/inet/ntp.bak"
-#define	NTP_CONF_TMP	"/etc/inet/ntp.tmp"
-#define	SMF_TZ_PGNAME	"environment"
-#define	SMF_TZ_PROPNAME	"TZ"
-#define	ZONEINFO_DIR	"/usr/share/lib/zoneinfo/" /* trailing / essential */
-
-/*ARGSUSED*/
-conerr_t
-interface_Time_read_time(rad_instance_t *inst, adr_attribute_t *attr,
-    adr_data_t **data, adr_data_t **error)
-{
-	*data = adr_data_new_time_now();
-	return (CE_OK);
-}
-
-#define	NSPERUS	(NANOSEC / MICROSEC)
-
-/*ARGSUSED*/
-conerr_t
-interface_Time_write_time(rad_instance_t *inst, adr_attribute_t *attr,
-    adr_data_t *data, adr_data_t **error)
-{
-	long long seconds = adr_data_to_time_secs(data);
-	int nanos = adr_data_to_time_nsecs(data);
-	int micros = nanos / NSPERUS;
-	time_t newtime;
-	struct timeval adj;
-
-	if (nanos - (micros * NSPERUS) >= NSPERUS / 2) {
-		micros++;
-		if (micros >= MICROSEC) {
-			seconds++;
-			micros = 0;
-		}
-	}
-
-	if (seconds > LONG_MAX)
-		return (CE_OBJECT);
-
-	newtime = (time_t)seconds;
-	adj.tv_sec = 0;
-	adj.tv_usec = micros;
-
-	if (stime(&newtime) == -1 || adjtime(&adj, NULL) == -1) {
-		if (errno == EPERM)
-			return (CE_PRIV);
-		return (CE_OBJECT);
-	}
-
-	return (CE_OK);
-}
-
-/*ARGSUSED*/
-conerr_t
-interface_Time_read_defaultTimeZone(rad_instance_t *inst, adr_attribute_t *attr,
-    adr_data_t **data, adr_data_t **error)
-{
-	char zonefile[PATH_MAX];
-	int n = snprintf(zonefile, PATH_MAX, "%s", ZONEINFO_DIR);
-	char *tz = zonefile + n;
-	conerr_t err = smfu_get_property((char *)SCF_INSTANCE_ENV,
-	    SMF_TZ_PGNAME, SMF_TZ_PROPNAME, tz, PATH_MAX - n);
-
-	if (err == CE_OK) {
-		/*
-		 * The stored time zone may be the name of a symlink
-		 * (i.e. "localtime"), under ZONEINFO_DIR.  Resolve that symlink
-		 * and pass the actual time zone to the client.
-		 */
-		char resolved[PATH_MAX];
-		if (realpath(zonefile, resolved) != NULL &&
-		    strncmp(resolved, ZONEINFO_DIR, n) == 0) {
-			tz = resolved + n;
-		}
-		*data = adr_data_new_string(tz, LT_COPY);
-	}
-
-	return (err);
-}
-
-/*ARGSUSED*/
-conerr_t
-interface_Time_write_defaultTimeZone(rad_instance_t *inst,
-    adr_attribute_t *attr, adr_data_t *data, adr_data_t **error)
-{
-	conerr_t err = smfu_set_property((char *)SCF_INSTANCE_ENV,
-	    SMF_TZ_PGNAME, SMF_TZ_PROPNAME, (char *)adr_data_to_string(data));
-	return (err);
-}
-
-static void
-removenl(char *str)
-{
-	char *nl = strchr(str, '\n');
-	if (nl != NULL)
-		*nl = '\0';
-}
-
-/* We only recognize the disabled entries we write */
-static const char *disabled = "# server ";
-static const char *enabled = "server ";
-static const char *ntpservers[] = {
-	"time.nist.gov",
-	"time-a.nist.gov",
-	"time-b.nist.gov",
-	"time-nw.nist.gov"
-};
-
-static const char * const si_server_path[] = { "server", NULL };
-
-static void
-disable(adr_data_t *array, const char *srv, int len)
-{
-	if (adr_array_nsearch(array, srv, len, si_server_path) >= 0)
-		return;
-	adr_data_t *entry = adr_data_new_struct(&t__ServerInfo);
-	adr_struct_set(entry, "server", adr_data_new_nstring(srv, len));
-	adr_struct_set(entry, "enabled", adr_data_new_boolean(B_FALSE));
-	(void) adr_array_add(array, entry);
-}
-
-static void
-enable(adr_data_t *array, const char *srv, int len)
-{
-	int index = adr_array_nsearch(array, srv, len, si_server_path);
-	if (index >= 0) {
-		adr_struct_set(adr_array_get(array, index), "enabled",
-		    adr_data_new_boolean(B_TRUE));
-		return;
-	}
-	adr_data_t *entry = adr_data_new_struct(&t__ServerInfo);
-	adr_struct_set(entry, "server", adr_data_new_nstring(srv, len));
-	adr_struct_set(entry, "enabled", adr_data_new_boolean(B_TRUE));
-	(void) adr_array_add(array, entry);
-}
-
-/*ARGSUSED*/
-conerr_t
-interface_Time_read_ntpServers(rad_instance_t *inst, adr_attribute_t *attr,
-    adr_data_t **data, adr_data_t **error)
-{
-	adr_data_t *result = adr_data_new_array(&t_array__ServerInfo, 4);
-	for (int i = 0; i < RAD_COUNT(ntpservers); i++) {
-		adr_data_t *si = adr_data_new_struct(&t__ServerInfo);
-		adr_struct_set(si, "server",
-		    adr_data_new_string(ntpservers[i], LT_COPY));
-		adr_struct_set(si, "enabled", adr_data_new_boolean(B_FALSE));
-		(void) adr_array_add(result, si);
-	}
-
-	FILE *file = fopen(NTP_CONF, "r");
-	if (file != NULL) {
-		char buf[1024];
-		while (fgets(buf, sizeof (buf), file) != NULL) {
-			boolean_t isenabled;
-			char *str = buf;
-
-			removenl(buf);
-			if (rad_strccmp(disabled, str, strlen(disabled)) == 0) {
-				isenabled = B_FALSE;
-				str += strlen(disabled);
-			} else if (rad_strccmp(enabled, str, strlen(enabled))
-			    == 0) {
-				isenabled = B_TRUE;
-				str += strlen(enabled);
-			} else {
-				continue;
-			}
-
-			int len = strcspn(str, " \t");
-			if (len == 0)
-				continue;
-			if (isenabled)
-				enable(result, str, len);
-			else
-				disable(result, str, len);
-		}
-		(void) fclose(file);
-	}
-
-	*data = result;
-	return (CE_OK);
-}
-
-/*ARGSUSED*/
-conerr_t
-interface_Time_read_sufficientlyPrivileged(rad_instance_t *inst,
-    adr_attribute_t *attr, adr_data_t **data, adr_data_t **error)
-{
-	/* XXX: Crude */
-	*data = adr_data_new_boolean(getuid() == 0);
-	return (CE_OK);
-}
-
-/*ARGSUSED*/
-conerr_t
-interface_Time_read_continents(rad_instance_t *inst, adr_attribute_t *attr,
-    adr_data_t **data, adr_data_t **error)
-{
-	FILE *file = fopen("/usr/share/lib/zoneinfo/tab/continent.tab", "r");
-	char str[1024];
-	adr_data_t *result = adr_data_new_array(&t_array__Continent, 5);
-	while (fgets(str, sizeof (str), file) != NULL) {
-		if (str[0] == '#')
-			continue;
-		removenl(str);
-
-		char *eq = strchr(str, '\t');
-		if (eq == NULL)
-			continue;
-		adr_data_t *name = adr_data_new_nstring(str, eq - str);
-		adr_data_t *desc = adr_data_new_string(eq + 1, LT_COPY);
-		adr_data_t *cont = adr_data_new_struct(&t__Continent);
-		adr_struct_set(cont, "name", name);
-		adr_struct_set(cont, "description", desc);
-		(void) adr_array_add(result, cont);
-	}
-	(void) fclose(file);
-	*data = result;
-
-	return (CE_OK);
-}
-
-/*ARGSUSED*/
-conerr_t
-interface_Time_read_countries(rad_instance_t *inst, adr_attribute_t *attr,
-    adr_data_t **data, adr_data_t **error)
-{
-	FILE *file = fopen("/usr/share/lib/zoneinfo/tab/country.tab", "r");
-	char str[1024];
-	adr_data_t *result = adr_data_new_array(&t_array__Country, 5);
-	while (fgets(str, sizeof (str), file) != NULL) {
-		if (str[0] == '#')
-			continue;
-		removenl(str);
-
-		char *eq = strchr(str, '\t');
-		if (eq == NULL)
-			continue;
-		if (rad_strccmp("ee", str, eq - str) == 0 ||
-		    rad_strccmp("we", str, eq - str) == 0 ||
-		    rad_strccmp("me", str, eq - str) == 0)
-			continue;
-		adr_data_t *code = adr_data_new_nstring(str, eq - str);
-		adr_data_t *desc = adr_data_new_string(eq + 1, LT_COPY);
-		adr_data_t *country = adr_data_new_struct(&t__Country);
-		adr_struct_set(country, "code", code);
-		adr_struct_set(country, "description", desc);
-		(void) adr_array_add(result, country);
-	}
-	(void) fclose(file);
-	*data = result;
-
-	return (CE_OK);
-}
-
-/*
- * Parse ISO 6709 -formatted coordinates
- */
-struct coord {
-	int deg;
-	int min;
-	int sec;
-};
-
-static boolean_t
-parse_coord(const char *str, int len, struct coord *c)
-{
-	char *dot = strchr(str, '.');
-	if (dot != NULL && dot < str + len)
-		len = dot - str;
-
-	if (len < 2 || len > 7)
-		return (B_FALSE);
-
-	if (len > 5) {
-		const char *fmt = (len & 1) ? "%3u%2u%2u" : "%2u%2u%2u";
-		return (sscanf(str, fmt, &c->deg, &c->min, &c->sec) == 3);
-	} else {
-		const char *fmt = (len & 1) ? "%3u%2u" : "%2u%2u";
-		return (sscanf(str, fmt, &c->deg, &c->min) == 2);
-	}
-}
-
-static adr_data_t *
-parse_coords(const char *str, int len)
-{
-	int isnorth, iseast;
-
-	if (len > 0 && str[0] == '+')
-		isnorth = 1;
-	else if (len > 0 && str[0] == '-')
-		isnorth = -1;
-	else
-		return (NULL);
-
-	str++;
-	len--;
-	char *eq = strchr(str, '+');
-	if (eq == NULL || eq >= str + len)
-		eq = strchr(str, '-');
-	if (eq == NULL || eq >= str + len)
-		return (NULL);
-	iseast = (*eq == '+') ? 1 : -1;
-
-	struct coord north = { 0 };
-	struct coord east = { 0 };
-
-	if (!parse_coord(str, eq - str, &north) ||
-	    !parse_coord(eq + 1, len - (eq - str + 1), &east))
-		return (NULL);
-
-	adr_data_t *result = adr_data_new_struct(&t__Coordinates);
-	adr_struct_set(result, "degreesE",
-	    adr_data_new_integer(east.deg * iseast));
-	adr_struct_set(result, "minutesE", adr_data_new_integer(east.min));
-	adr_struct_set(result, "secondsE", adr_data_new_integer(east.sec));
-	adr_struct_set(result, "degreesN",
-	    adr_data_new_integer(north.deg * isnorth));
-	adr_struct_set(result, "minutesN", adr_data_new_integer(north.min));
-	adr_struct_set(result, "secondsN", adr_data_new_integer(north.sec));
-	return (result);
-}
-
-/*ARGSUSED*/
-conerr_t
-interface_Time_read_timeZones(rad_instance_t *inst, adr_attribute_t *attr,
-    adr_data_t **data, adr_data_t **error)
-{
-	FILE *file = fopen("/usr/share/lib/zoneinfo/tab/zone_sun.tab", "r");
-	char buf[1024];
-	adr_data_t *result = adr_data_new_array(&t_array__TimeZoneInfo, 5);
-	while (fgets(buf, sizeof (buf), file) != NULL) {
-		char *str = buf;
-		if (str[0] == '#')
-			continue;
-		removenl(str);
-
-		char *eq = strchr(str, '\t');
-		if (eq == NULL)
-			continue;
-		if (rad_strccmp("ee", str, eq - str) == 0 ||
-		    rad_strccmp("we", str, eq - str) == 0 ||
-		    rad_strccmp("me", str, eq - str) == 0)
-			continue;
-		adr_data_t *timezone = adr_data_new_struct(&t__TimeZoneInfo);
-		adr_struct_set(timezone, "countryCode",
-		    adr_data_new_nstring(str, eq - str));
-
-		str = eq + 1;
-		eq = strchr(str, '\t');
-		adr_data_t *coords;
-		if (eq == NULL ||
-		    (coords = parse_coords(str, eq - str)) == NULL) {
-			adr_data_free(timezone);
-			continue;
-		}
-		adr_struct_set(timezone, "coordinates", coords);
-
-		str = eq + 1;
-		eq = strchr(str, '\t');
-		adr_data_t *tz = eq != NULL ?
-		    adr_data_new_nstring(str, eq - str) :
-		    adr_data_new_string(str, LT_COPY);
-		adr_struct_set(timezone, "name", tz);
-		if (eq == NULL)
-			goto done;
-
-		str = eq + 1;
-		eq = strchr(str, '\t');
-		if (eq != NULL) {
-			if (rad_strccmp("-", str, eq - str) != 0)
-				adr_struct_set(timezone, "altName",
-				    adr_data_new_nstring(str, eq - str));
-		} else {
-			if (strcmp("-", str) != 0)
-				adr_struct_set(timezone, "altName",
-				    adr_data_new_string(str, LT_COPY));
-			goto done;
-		}
-
-		str = eq + 1;
-		if (*str != '\0' && strcmp(str, "-") != 0)
-			adr_struct_set(timezone, "comments",
-			    adr_data_new_string(str, LT_COPY));
-
-done:
-		(void) adr_array_add(result, timezone);
-	}
-	(void) fclose(file);
-	*data = result;
-
-	return (CE_OK);
-}
-
-/*ARGSUSED*/
-conerr_t
-interface_Time_write_ntpServers(rad_instance_t *inst, adr_attribute_t *attr,
-    adr_data_t *data, adr_data_t **error)
-{
-	FILE *from, *to, *tmp; /* Read, write, & temp files */
-	int err = 0; /* Indicates an error */
-	int size = 256; /* Buffer size */
-	char buffer[size]; /* Read buffer */
-	size_t ch; /* Number chars read */
-
-	/* Copy file to preserve ntp.conf upon error */
-	from = fopen(NTP_CONF, "r");
-	if (from == NULL) {
-		if (errno == ENOENT) {
-			goto nobackup;
-		}
-		err = errno;
-		goto errorout;
-	}
-
-	to = fopen(NTP_CONF_BAK, "w");
-	if (to == NULL) {
-		err = errno;
-		(void) fclose(from);
-		goto errorout;
-	}
-
-	while ((ch = fread(buffer, 1, size, from)) > 0) {
-		if (fwrite(buffer, 1, ch, to) != ch) {
-			break;
-		}
-	}
-
-	if (ferror(from) || ferror(to)) {
-		// errno might be overwritten by fclose
-		err = errno;
-	}
-
-	(void) fclose(from);
-	(void) fclose(to);
-
-	if (err != 0)
-		goto errorout;
-
-nobackup:
-	/* Create temp file */
-	tmp = fopen(NTP_CONF_TMP, "w");
-	if (tmp == NULL) {
-		err = errno;
-		(void) fclose(tmp);
-		goto errorout;
-	}
-
-	for (int i = 0; i < adr_array_size(data); i++) {
-		adr_data_t *entry = adr_array_get(data, i);
-		adr_data_t *enabled = adr_struct_get(entry, "enabled");
-		adr_data_t *server = adr_struct_get(entry, "server");
-		if (fprintf(tmp,
-		    adr_data_to_boolean(enabled) ? "server %s\n" :
-		    "# server %s\n", adr_data_to_string(server)) < 0)
-			goto writefailed;
-	}
-	if (fclose(tmp) == EOF)
-		goto writefailed;
-
-	/* Rename temp file */
-	if (chmod(NTP_CONF_TMP, 0644) == 0 &&
-	    rename(NTP_CONF_TMP, NTP_CONF) == 0)
-		return (CE_OK);
-
-writefailed:
-	err = errno;
-	(void) unlink(NTP_CONF_TMP);
-
-errorout:
-	return (err == EACCES ? CE_PRIV : CE_OBJECT);
-}
-
-int
-_rad_init(void)
-{
-	adr_name_t *aname = adr_name_vcreate(MOD_DOMAIN, 1, "type", "Time");
-	conerr_t cerr =  rad_cont_insert_singleton(rad_container, aname,
-	    &modinfo, &interface_Time_svr);
-	adr_name_rele(aname);
-	if (cerr != CE_OK) {
-		rad_log(RL_ERROR, "(mod_time) failed to insert Time");
-		return (-1);
-	}
-
-	return (0);
-}
-
-/*
- * _rad_fini is called by the RAD daemon when the module is unloaded. Any
- * module finalisation is completed here.
- */
-/*ARGSUSED*/
-void
-_rad_fini(void *unused)
-{
-}