From ca57057f598bfc7119f79f71bf38ec88244ab396 Mon Sep 17 00:00:00 2001 From: Cy Schubert Date: Wed, 31 Aug 2016 00:08:49 +0000 Subject: Import am-utils 6.2, Suggested by: pfg@ Obtained from: ftp://ftp.am-utils.org/pub/am-utils/ --- amd/sun_map.c | 595 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 595 insertions(+) create mode 100644 amd/sun_map.c (limited to 'amd/sun_map.c') diff --git a/amd/sun_map.c b/amd/sun_map.c new file mode 100644 index 000000000000..8e3559960cd3 --- /dev/null +++ b/amd/sun_map.c @@ -0,0 +1,595 @@ +/* + * Copyright (c) 1997-2014 Erez Zadok + * Copyright (c) 2005 Daniel P. Ottavio + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * + * File: am-utils/amd/sun_map.c + * + */ + +#ifdef HAVE_CONFIG_H +# include +#endif /* HAVE_CONFIG_H */ +#include +#include +#include + + + +/* + * Add a data pointer to the end of the list. + */ +void +sun_list_add(struct sun_list *list, qelem *item) +{ + if (list->last == NULL) { + list->last = item; + list->first = item; + item->q_back = NULL; + } + else { + list->last->q_forw = item; + item->q_back = list->last; + list->last = item; + } + + item->q_forw = NULL; +} + + +/* + * Sun2Amd conversion routines + */ + +/* + * AMD entry keywords + */ +#define AMD_OPTS_KW "addopts:=" /* add entry options */ +#define AMD_RHOST_KW "rhost:=" /* remote host */ +#define AMD_RFS_KW "rfs:=" /* remote file system */ +#define AMD_FS_KW "fs:=" /* local file system */ +#define AMD_DEV_KW "dev:=" /* device */ +#define AMD_TYPE_NFS_KW "type:=nfs;" /* fs type nfs */ +#define AMD_TYPE_AUTO_KW "type:=auto;" /* fs type auto */ +#define AMD_TYPE_CDFS_KW "type:=cdfs;" /* fs type cd */ +#define AMD_MAP_FS_KW "fs:=${map};" /* set the mount map as current map */ +#define AMD_MAP_PREF_KW "pref:=${key}/" /* set the mount map as current map */ + +/* + * A set of string Sun fstypes. + */ +#define SUN_NFS_TYPE "nfs" +#define SUN_HSFS_TYPE "hsfs" /* CD fs */ +#define SUN_AUTOFS_TYPE "autofs" +#define SUN_CACHEFS_TYPE "cachefs" + +#define SUN_KEY_SUB "&" /* Sun key substitution */ + +/* a set a Sun variable substitutions for map entries */ +#define SUN_ARCH "$ARCH" /* host architecture */ +#define SUN_CPU "$CPU" /* processor type */ +#define SUN_HOST "$HOST" /* host name */ +#define SUN_OSNAME "$OSNAME" /* OS name */ +#define SUN_OSREL "$OSREL" /* OS release */ +#define SUN_OSVERS "$OSVERS" /* OS version */ +#define SUN_NATISA "$NATISA" /* native instruction set */ + +/* a set of Amd variable substitutions */ +#define AMD_ARCH "${arch}" /* host architecture */ +#define AMD_HOST "${host}" /* host name */ +#define AMD_OSNAME "${os}" /* OS name */ +#define AMD_OSVER "${osver}" /* OS version */ + + +/* + * Return a copy of src that has all occurrences of 'str' replaced + * with sub. + * + * param src - the original string + * param str - string that is the replaced with str + * param sub - string that replaces an occurrences of 'delim' + * + * return - new string with str substitutions, NULL on error + */ +static char * +sun_strsub(const char *src, const char *str, const char *sub) +{ + + char *retval = NULL, *str_start, *str_end, *src_end; + size_t total_size, first_half, second_half, sub_size; + + /* assign pointers to the start and end of str */ + if ((str_start = strstr(src, str)) == NULL) { + return retval; + } + str_end = (strlen(str) - 1) + str_start; + + /* assign to the end of the src. */ + src_end = (strlen(src) - 1) + (char*)src; + + /* size from the beginning of src to the start of str */ + first_half = (size_t)(str_start - src); + + /* size from the end of str to the end of src */ + second_half = (size_t)(src_end - str_end); + + sub_size = strlen(sub); + + total_size = (first_half + sub_size + second_half + 1); + + retval = (char*)xmalloc(total_size); + memset(retval, 0, total_size); + + /* + * Put together the string such that the first half is copied + * followed the sub and second half. + * + * We use strncpy instead of xstrlcpy because we are intentionally + * causing truncation and we don't want this to cause errors in the + * log. + */ + (void)strncpy(retval, src, first_half); + (void)strncat(retval, sub, sub_size); + (void)strncat(retval, str_end + 1, second_half); + + if (strstr(retval, str) != NULL) { + /* + * If there is another occurrences of str call this function + * recursively. + */ + char* tmp; + if ((tmp = sun_strsub(retval, str, sub)) != NULL) { + XFREE(retval); + retval = tmp; + } + } + return retval; +} + + +/* + * Return a new string that is a copy of str, all occurrences of a Sun + * variable substitutions are replaced by there equivalent Amd + * substitutions. + * + * param str - source string + * + * return - A new string with the expansions, NULL if str does not + * exist in src or error. + */ +static char * +sun_expand2amd(const char *str) +{ + + char *retval = NULL, *tmp = NULL, *tmp2 = NULL; + const char *pos; + + /* + * Iterator through the string looking for '$' chars. For each '$' + * found try to replace it with Sun variable substitutions. If we + * find a '$' that is not a substation each of the i.e $blah than + * each of the replace attempt will fail and we'll move on to the + * next char. + */ + tmp = xstrdup(str); + for (pos = str; *pos != '\0'; pos++) { + if (*pos != '$') { + continue; + } + if (tmp2 != NULL) { + XFREE(tmp); + tmp = tmp2; + } + + /* + * If a 'replace' does not return NULL than a variable was + * successfully substituted. + */ + + /* architecture */ + if ((tmp2 = sun_strsub(tmp, SUN_ARCH, AMD_ARCH)) != NULL) { + continue; + } + /* cpu - there is not POSIX uname for cpu so just use machine */ + if ((tmp2 = sun_strsub(tmp, SUN_CPU, AMD_ARCH)) != NULL) { + continue; + } + /* hostname */ + if ((tmp2 = sun_strsub(tmp, SUN_HOST, AMD_HOST)) != NULL) { + continue; + } + /* os name */ + if ((tmp2 = sun_strsub(tmp, SUN_OSNAME, AMD_OSNAME)) != NULL) { + continue; + } + /* + * os release - Amd doesn't hava a OS release var just usr os + * version or now. + */ + if ((tmp2 = sun_strsub(tmp, SUN_OSREL, AMD_OSVER)) != NULL) { + continue; + } + /* os version */ + if ((tmp2 = sun_strsub(tmp, SUN_OSVERS, AMD_OSVER)) != NULL) { + continue; + } + /* native instruction set - there is no POSIX natisa so just use system */ + if ((tmp2 = sun_strsub(tmp, SUN_NATISA, AMD_ARCH)) != NULL) { + continue; + } + } + if (tmp2 == NULL) { + retval = tmp; + } + else { + retval = tmp2; + XFREE(tmp); + } + + return retval; +} + + +/* + * This is a wrapper function for appending Amd entry information to a + * buffer. Any Sun variable substitutions will be converted into Amd + * equivalents. + * + * param dest - destination buffer + * param deslen - destination buffer length + * param key - entry key, this might be needed for key substitutions + * param str - string to append + */ +static void +sun_append_str(char *dest, + size_t destlen, + const char *key, + const char *str) +{ + char *sub = NULL, *sub2 = NULL, *out = NULL; + + /* By default we are going to just write the original string. */ + out = (char*)str; + + /* + * Resolve variable substitutions in two steps; 1) replace any key + * map substitutions with the entry key 2) expand any variable + * substitutions i.e $HOST. + * + * Try to replace the key substitution '&'. If this function returns + * with a new string, one or more key subs. where replaced with the + * entry key. + */ + if ((sub = sun_strsub(str, SUN_KEY_SUB, "${key}")) != NULL) { + out = sub; + /* + * Try to convert any variable substitutions. If this function + * returns a new string one or more var subs where expanded. + */ + if ((sub2 = sun_expand2amd(sub)) != NULL) { + out = sub2; + } + } + /* + * Try to convert any variable substitutions. If this function + * returns a new string one or more var subs where expanded. + */ + else if (out != NULL && (sub = sun_expand2amd(out)) != NULL) { + out = sub; + } + + if (out != NULL) { + xstrlcat(dest, out, destlen); + } + XFREE(sub); + XFREE(sub2); +} + + +/* + * Convert the list of Sun mount options to Amd mount options. The + * result is concatenated to dest. + * + * param dest - destination buffer + * param destlen - destination buffer length + * param key - automount key + * param opt_list - list of Sun mount options + */ +static void +sun_opts2amd(char *dest, + size_t destlen, + const char *key, + const struct sun_opt *opt_list) +{ + const struct sun_opt *opt; + + xstrlcat(dest, AMD_OPTS_KW, destlen); + + /* Iterate through each option and append it to the buffer. */ + for(opt = opt_list; opt != NULL; opt = NEXT(struct sun_opt, opt)) { + sun_append_str(dest, destlen, key, opt->str); + /* If there are more options add some commas. */ + if (NEXT(struct sun_opt, opt) != NULL) { + xstrlcat(dest, ",", destlen); + } + } + xstrlcat(dest, ";", destlen); +} + + +/* + * Convert the list of Sun mount locations to a list of Amd mount + * locations. The result is concatenated to dest. + * + * param dest - destination buffer + * param destlen - destination buffer length + * param key - automount key + * param local_list - list of Sun mount locations + */ +static void +sun_locations2amd(char *dest, + size_t destlen, + const char *key, + const struct sun_location *local_list) +{ + const struct sun_location *local; + const struct sun_host *host; + + for (local = local_list; + local != NULL; + local = NEXT(struct sun_location,local)) { + /* + * Check to see if the list of hosts is empty. Some mount types + * i.e cd-rom may have mount location with no host. + */ + if (local->host_list != NULL) { + /* Write each host that belongs to this location. */ + for (host = local->host_list; + host != NULL; + host = NEXT(struct sun_host, host)) { + /* set fstype NFS */ + xstrlcat(dest, AMD_TYPE_NFS_KW, destlen); + /* add rhost key word */ + xstrlcat(dest, AMD_RHOST_KW, destlen); + /* add host name */ + sun_append_str(dest, destlen, key, host->name); + xstrlcat(dest, ";", destlen); + /* add remote fs key word */ + xstrlcat(dest, AMD_RFS_KW, destlen); + /* add local path */ + sun_append_str(dest, destlen, key, local->path); + if (NEXT(struct sun_host, host) != NULL) { + xstrlcat(dest, ";", destlen); + xstrlcat(dest, " ", destlen); + } + } + } + else { + /* no host location */ + xstrlcat(dest, AMD_FS_KW, destlen); + sun_append_str(dest, destlen, key, local->path); + } + if (NEXT(struct sun_location, local) != NULL) { + /* add a space to separate each location */ + xstrlcat(dest, " ", destlen); + } + } +} + + +/* + * Convert a Sun HSFS mount point to an Amd. The result is + * concatenated intp dest. + * + * param dest - destination buffer + * param destlen - destination buffer length + * param key - automount key + * param s_entry - Sun entry + */ +static void +sun_hsfs2amd(char *dest, + size_t destlen, + const char *key, + const struct sun_entry *s_entry) +{ + /* set fstype CDFS */ + xstrlcat(dest, AMD_TYPE_CDFS_KW, destlen); + /* set the cdrom device */ + xstrlcat(dest, AMD_DEV_KW, destlen); + /* XXX: For now just assume that there is only one device. */ + xstrlcat(dest, s_entry->location_list->path, destlen); +} + + +/* + * Convert a Sun NFS automount entry to an Amd. The result is concatenated + * into dest. + * + * param dest - destination buffer + * param destlen - destination buffer length + * param key - automount key + * param s_entry - Sun entry + */ +static void +sun_nfs2amd(char *dest, + size_t destlen, + const char *key, + const struct sun_entry *s_entry) +{ + if (s_entry->location_list != NULL) { + /* write out the list of mountpoint locations */ + sun_locations2amd(dest, destlen, key, s_entry->location_list); + } +} + + +/* + * Convert a Sun multi-mount point entry to an Amd. This is done + * using the Amd type auto. Each auto entry is separated with a \n. + * + * param dest - destination buffer + * param destlen - destination buffer length + * param key - automount key + * param s_entry - Sun entry + */ +static void +sun_multi2amd(char *dest, + size_t destlen, + const char *key, + const struct sun_entry *s_entry) +{ + const struct sun_mountpt *mountpt; + + /* We need to setup a auto fs Amd automount point. */ + xstrlcat(dest, AMD_TYPE_AUTO_KW, destlen); + xstrlcat(dest, AMD_MAP_FS_KW, destlen); + xstrlcat(dest, AMD_MAP_PREF_KW, destlen); + + /* write the mountpts to dest */ + for (mountpt = s_entry->mountpt_list; + mountpt != NULL; + mountpt = NEXT(struct sun_mountpt, mountpt)) { + xstrlcat(dest, "\n", destlen); + /* write the key */ + xstrlcat(dest, key, destlen); + /* write the mount path */ + sun_append_str(dest, destlen, key, mountpt->path); + /* space */ + xstrlcat(dest, " ", destlen); + /* Write all the host locations for this mount point. */ + sun_locations2amd(dest, destlen, key, mountpt->location_list); + } +} + + +/* + * Convert the sun_entry into an Amd equivalent string. + * + * param key - automount key + * param s_entry - Sun style automap entry + * + * return - Amd entry on succes, NULL on error + */ +char * +sun_entry2amd(const char *key, const char *s_entry_str) +{ + char *retval = NULL; + char line_buff[INFO_MAX_LINE_LEN]; + int ws; + struct sun_entry *s_entry = NULL; + + /* The key should not be NULL. */ + if (key == NULL) { + plog(XLOG_ERROR,"Sun key value was null"); + goto err; + } + /* The Sun entry string should never be NULL. */ + if (s_entry_str == NULL) { + plog(XLOG_ERROR,"Sun entry value was null"); + goto err; + } + + /* Make sure there are no trailing white spaces or '\n'. */ + xstrlcpy(line_buff, s_entry_str, sizeof(line_buff)); + ws = strlen(line_buff) - 1; + while (ws >= 0 && (isspace((unsigned char)line_buff[ws]) || line_buff[ws] == '\n')) { + line_buff[ws--] = '\0'; + } + + /* Parse the sun entry line. */ + s_entry = sun_map_parse_read(line_buff); + if (s_entry == NULL) { + plog(XLOG_ERROR,"could not parse Sun style map"); + goto err; + } + + memset(line_buff, 0, sizeof(line_buff)); + + if (s_entry->opt_list != NULL) { + /* write the mount options to the buffer */ + sun_opts2amd(line_buff, sizeof(line_buff), key, s_entry->opt_list); + } + + /* Check if this is a multi-mount entry. */ + if (s_entry->mountpt_list != NULL) { + /* multi-mount point */ + sun_multi2amd(line_buff, sizeof(line_buff), key, s_entry); + retval = xstrdup(line_buff); + } + else { + /* single mount point */ + if (s_entry->fstype != NULL) { + if (NSTREQ(s_entry->fstype, SUN_NFS_TYPE, strlen(SUN_NFS_TYPE))) { + /* NFS Type */ + sun_nfs2amd(line_buff, sizeof(line_buff), key, s_entry); + retval = xstrdup(line_buff); + } + else if (NSTREQ(s_entry->fstype, SUN_HSFS_TYPE, strlen(SUN_HSFS_TYPE))) { + /* HSFS Type (CD fs) */ + sun_hsfs2amd(line_buff, sizeof(line_buff), key, s_entry); + retval = xstrdup(line_buff); + } + /* + * XXX: The following fstypes are not yet supported. + */ + else if (NSTREQ(s_entry->fstype, SUN_AUTOFS_TYPE, strlen(SUN_AUTOFS_TYPE))) { + /* AutoFS Type */ + plog(XLOG_ERROR, "Sun fstype %s is currently not supported by Amd.", + s_entry->fstype); + goto err; + + } + else if (NSTREQ(s_entry->fstype, SUN_CACHEFS_TYPE, strlen(SUN_CACHEFS_TYPE))) { + /* CacheFS Type */ + plog(XLOG_ERROR, "Sun fstype %s is currently not supported by Amd.", + s_entry->fstype); + goto err; + } + else { + plog(XLOG_ERROR, "Sun fstype %s is currently not supported by Amd.", + s_entry->fstype); + goto err; + } + } + else { + plog(XLOG_INFO, "No SUN fstype specified defaulting to NFS."); + sun_nfs2amd(line_buff, sizeof(line_buff), key, s_entry); + retval = xstrdup(line_buff); + } + } + + err: + XFREE(s_entry); + return retval; +} -- cgit v1.2.3